summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLLVM libc <llvm-libc@google.com>2024-04-05 18:06:12 +0530
committerCopybara-Service <copybara-worker@google.com>2024-04-05 11:04:00 -0700
commitafe527ab9651fa77716706a96ddba233e078de55 (patch)
tree16cbe89196213c974abe1af0fb7f0559ccce36e8
parent52153e27ed3cac945247e6b1eeba1385efb78f6f (diff)
downloadllvm-libc-afe527ab9651fa77716706a96ddba233e078de55.tar.gz
Project import generated by Copybara.
GitOrigin-RevId: 3b961d113e6986eb9a6b448b72a730c289b8e6ab Change-Id: I9b459fafe52e3f2f19dc1ae4b306f3d7dc6178f9
-rw-r--r--include/__llvm-libc-common.h6
-rw-r--r--include/llvm-libc-macros/containerof-macro.h8
-rw-r--r--include/llvm-libc-macros/fcntl-macros.h6
-rw-r--r--include/llvm-libc-macros/features-macros.h6
-rw-r--r--include/llvm-libc-macros/fenv-macros.h6
-rw-r--r--include/llvm-libc-macros/file-seek-macros.h6
-rw-r--r--include/llvm-libc-macros/float-macros.h7
-rw-r--r--include/llvm-libc-macros/generic-error-number-macros.h6
-rw-r--r--include/llvm-libc-macros/gpu/time-macros.h6
-rw-r--r--include/llvm-libc-macros/inttypes-macros.h420
-rw-r--r--include/llvm-libc-macros/limits-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/fcntl-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sched-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/signal-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-ioctl-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-random-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-resource-macros.h5
-rw-r--r--include/llvm-libc-macros/linux/sys-socket-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-stat-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-time-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/sys-wait-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/termios-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/time-macros.h6
-rw-r--r--include/llvm-libc-macros/linux/unistd-macros.h6
-rw-r--r--include/llvm-libc-macros/math-macros.h77
-rw-r--r--include/llvm-libc-macros/null-macro.h6
-rw-r--r--include/llvm-libc-macros/offsetof-macro.h6
-rw-r--r--include/llvm-libc-macros/sched-macros.h6
-rw-r--r--include/llvm-libc-macros/signal-macros.h6
-rw-r--r--include/llvm-libc-macros/stdbit-macros.h286
-rw-r--r--include/llvm-libc-macros/stdckdint-macros.h25
-rw-r--r--include/llvm-libc-macros/stdfix-macros.h328
-rw-r--r--include/llvm-libc-macros/stdint-macros.h878
-rw-r--r--include/llvm-libc-macros/stdio-macros.h10
-rw-r--r--include/llvm-libc-macros/stdlib-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-auxv-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-ioctl-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-mman-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-queue-macros.h62
-rw-r--r--include/llvm-libc-macros/sys-random-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-resource-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-select-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-socket-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-stat-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-time-macros.h6
-rw-r--r--include/llvm-libc-macros/sys-wait-macros.h6
-rw-r--r--include/llvm-libc-macros/termios-macros.h6
-rw-r--r--include/llvm-libc-macros/time-macros.h6
-rw-r--r--include/llvm-libc-macros/unistd-macros.h6
-rw-r--r--include/llvm-libc-macros/wchar-macros.h6
-rw-r--r--include/llvm-libc-types/ACTION.h6
-rw-r--r--include/llvm-libc-types/DIR.h6
-rw-r--r--include/llvm-libc-types/ENTRY.h6
-rw-r--r--include/llvm-libc-types/FILE.h6
-rw-r--r--include/llvm-libc-types/__atexithandler_t.h6
-rw-r--r--include/llvm-libc-types/__atfork_callback_t.h6
-rw-r--r--include/llvm-libc-types/__bsearchcompare_t.h6
-rw-r--r--include/llvm-libc-types/__call_once_func_t.h6
-rw-r--r--include/llvm-libc-types/__exec_argv_t.h6
-rw-r--r--include/llvm-libc-types/__exec_envp_t.h6
-rw-r--r--include/llvm-libc-types/__futex_word.h6
-rw-r--r--include/llvm-libc-types/__getoptargv_t.h6
-rw-r--r--include/llvm-libc-types/__mutex_type.h8
-rw-r--r--include/llvm-libc-types/__pthread_once_func_t.h6
-rw-r--r--include/llvm-libc-types/__pthread_start_t.h6
-rw-r--r--include/llvm-libc-types/__pthread_tss_dtor_t.h6
-rw-r--r--include/llvm-libc-types/__qsortcompare_t.h6
-rw-r--r--include/llvm-libc-types/__qsortrcompare_t.h6
-rw-r--r--include/llvm-libc-types/__sighandler_t.h6
-rw-r--r--include/llvm-libc-types/__thread_type.h6
-rw-r--r--include/llvm-libc-types/blkcnt_t.h6
-rw-r--r--include/llvm-libc-types/blksize_t.h6
-rw-r--r--include/llvm-libc-types/cc_t.h6
-rw-r--r--include/llvm-libc-types/clock_t.h6
-rw-r--r--include/llvm-libc-types/clockid_t.h6
-rw-r--r--include/llvm-libc-types/cnd_t.h6
-rw-r--r--include/llvm-libc-types/cookie_io_functions_t.h12
-rw-r--r--include/llvm-libc-types/cpu_set_t.h6
-rw-r--r--include/llvm-libc-types/dev_t.h6
-rw-r--r--include/llvm-libc-types/div_t.h6
-rw-r--r--include/llvm-libc-types/double_t.h6
-rw-r--r--include/llvm-libc-types/fd_set.h8
-rw-r--r--include/llvm-libc-types/fenv_t.h6
-rw-r--r--include/llvm-libc-types/fexcept_t.h6
-rw-r--r--include/llvm-libc-types/float128.h36
-rw-r--r--include/llvm-libc-types/float_t.h6
-rw-r--r--include/llvm-libc-types/fsblkcnt_t.h14
-rw-r--r--include/llvm-libc-types/fsfilcnt_t.h14
-rw-r--r--include/llvm-libc-types/gid_t.h6
-rw-r--r--include/llvm-libc-types/ino_t.h6
-rw-r--r--include/llvm-libc-types/jmp_buf.h6
-rw-r--r--include/llvm-libc-types/ldiv_t.h6
-rw-r--r--include/llvm-libc-types/lldiv_t.h6
-rw-r--r--include/llvm-libc-types/mbstate_t.h16
-rw-r--r--include/llvm-libc-types/mode_t.h6
-rw-r--r--include/llvm-libc-types/mtx_t.h8
-rw-r--r--include/llvm-libc-types/nlink_t.h6
-rw-r--r--include/llvm-libc-types/off64_t.h6
-rw-r--r--include/llvm-libc-types/off_t.h6
-rw-r--r--include/llvm-libc-types/once_flag.h8
-rw-r--r--include/llvm-libc-types/pid_t.h6
-rw-r--r--include/llvm-libc-types/posix_spawn_file_actions_t.h6
-rw-r--r--include/llvm-libc-types/posix_spawnattr_t.h6
-rw-r--r--include/llvm-libc-types/pthread_attr_t.h8
-rw-r--r--include/llvm-libc-types/pthread_key_t.h6
-rw-r--r--include/llvm-libc-types/pthread_mutex_t.h8
-rw-r--r--include/llvm-libc-types/pthread_mutexattr_t.h6
-rw-r--r--include/llvm-libc-types/pthread_once_t.h8
-rw-r--r--include/llvm-libc-types/pthread_t.h8
-rw-r--r--include/llvm-libc-types/rlim_t.h6
-rw-r--r--include/llvm-libc-types/rpc_opcodes_t.h9
-rw-r--r--include/llvm-libc-types/sa_family_t.h6
-rw-r--r--include/llvm-libc-types/sig_atomic_t.h6
-rw-r--r--include/llvm-libc-types/siginfo_t.h14
-rw-r--r--include/llvm-libc-types/sigset_t.h8
-rw-r--r--include/llvm-libc-types/size_t.h6
-rw-r--r--include/llvm-libc-types/socklen_t.h6
-rw-r--r--include/llvm-libc-types/speed_t.h6
-rw-r--r--include/llvm-libc-types/ssize_t.h6
-rw-r--r--include/llvm-libc-types/stack_t.h8
-rw-r--r--include/llvm-libc-types/struct_dirent.h10
-rw-r--r--include/llvm-libc-types/struct_epoll_data.h21
-rw-r--r--include/llvm-libc-types/struct_epoll_event.h19
-rw-r--r--include/llvm-libc-types/struct_hsearch_data.h6
-rw-r--r--include/llvm-libc-types/struct_rlimit.h8
-rw-r--r--include/llvm-libc-types/struct_rusage.h8
-rw-r--r--include/llvm-libc-types/struct_sched_param.h12
-rw-r--r--include/llvm-libc-types/struct_sigaction.h10
-rw-r--r--include/llvm-libc-types/struct_sockaddr.h8
-rw-r--r--include/llvm-libc-types/struct_sockaddr_un.h8
-rw-r--r--include/llvm-libc-types/struct_stat.h26
-rw-r--r--include/llvm-libc-types/struct_statvfs.h29
-rw-r--r--include/llvm-libc-types/struct_termios.h6
-rw-r--r--include/llvm-libc-types/struct_timespec.h8
-rw-r--r--include/llvm-libc-types/struct_timeval.h10
-rw-r--r--include/llvm-libc-types/struct_tm.h6
-rw-r--r--include/llvm-libc-types/struct_utsname.h6
-rw-r--r--include/llvm-libc-types/suseconds_t.h6
-rw-r--r--include/llvm-libc-types/tcflag_t.h6
-rw-r--r--include/llvm-libc-types/test_rpc_opcodes_t.h6
-rw-r--r--include/llvm-libc-types/thrd_start_t.h6
-rw-r--r--include/llvm-libc-types/thrd_t.h8
-rw-r--r--include/llvm-libc-types/time_t.h6
-rw-r--r--include/llvm-libc-types/tss_dtor_t.h6
-rw-r--r--include/llvm-libc-types/tss_t.h6
-rw-r--r--include/llvm-libc-types/uid_t.h6
-rw-r--r--include/llvm-libc-types/union_sigval.h6
-rw-r--r--include/llvm-libc-types/wchar_t.h6
-rw-r--r--include/llvm-libc-types/wint_t.h6
-rw-r--r--include/sys/queue.h8
-rw-r--r--src/__support/CPP/array.h29
-rw-r--r--src/__support/CPP/atomic.h91
-rw-r--r--src/__support/CPP/bit.h139
-rw-r--r--src/__support/CPP/expected.h10
-rw-r--r--src/__support/CPP/iterator.h98
-rw-r--r--src/__support/CPP/limits.h5
-rw-r--r--src/__support/CPP/string_view.h21
-rw-r--r--src/__support/CPP/type_traits.h2
-rw-r--r--src/__support/CPP/type_traits/add_pointer.h1
-rw-r--r--src/__support/CPP/type_traits/decay.h1
-rw-r--r--src/__support/CPP/type_traits/is_constant_evaluated.h21
-rw-r--r--src/__support/CPP/type_traits/is_destructible.h3
-rw-r--r--src/__support/CPP/type_traits/is_fixed_point.h46
-rw-r--r--src/__support/CPP/type_traits/is_floating_point.h6
-rw-r--r--src/__support/CPP/type_traits/is_function.h3
-rw-r--r--src/__support/CPP/type_traits/is_integral.h3
-rw-r--r--src/__support/CPP/type_traits/is_lvalue_reference.h3
-rw-r--r--src/__support/CPP/type_traits/is_reference.h3
-rw-r--r--src/__support/CPP/type_traits/is_rvalue_reference.h3
-rw-r--r--src/__support/CPP/type_traits/is_trivially_copyable.h1
-rw-r--r--src/__support/CPP/type_traits/is_trivially_destructible.h5
-rw-r--r--src/__support/CPP/type_traits/make_signed.h3
-rw-r--r--src/__support/CPP/type_traits/make_unsigned.h3
-rw-r--r--src/__support/CPP/type_traits/remove_all_extents.h3
-rw-r--r--src/__support/FPUtil/BasicOperations.h195
-rw-r--r--src/__support/FPUtil/FEnvImpl.h4
-rw-r--r--src/__support/FPUtil/FPBits.h412
-rw-r--r--src/__support/FPUtil/ManipulationFunctions.h160
-rw-r--r--src/__support/FPUtil/NearestIntegerOperations.h139
-rw-r--r--src/__support/FPUtil/NormalFloat.h4
-rw-r--r--src/__support/FPUtil/XFloat.h180
-rw-r--r--src/__support/FPUtil/aarch64/fenv_darwin_impl.h8
-rw-r--r--src/__support/FPUtil/dyadic_float.h110
-rw-r--r--src/__support/FPUtil/fpbits_str.h7
-rw-r--r--src/__support/FPUtil/generic/FMod.h143
-rw-r--r--src/__support/FPUtil/generic/sqrt.h30
-rw-r--r--src/__support/FPUtil/generic/sqrt_80_bit_long_double.h21
-rw-r--r--src/__support/FPUtil/gpu/FMA.h8
-rw-r--r--src/__support/FPUtil/x86_64/NextUpDownLongDouble.h60
-rw-r--r--src/__support/FPUtil/x86_64/sqrt.h2
-rw-r--r--src/__support/File/file.h4
-rw-r--r--src/__support/GPU/allocator.cpp45
-rw-r--r--src/__support/GPU/allocator.h23
-rw-r--r--src/__support/GPU/amdgpu/utils.h55
-rw-r--r--src/__support/GPU/generic/utils.h14
-rw-r--r--src/__support/GPU/nvptx/utils.h35
-rw-r--r--src/__support/GPU/utils.h27
-rw-r--r--src/__support/HashTable/table.h6
-rw-r--r--src/__support/OSUtil/baremetal/io.cpp22
-rw-r--r--src/__support/OSUtil/baremetal/io.h7
-rw-r--r--src/__support/OSUtil/baremetal/quick_exit.cpp (renamed from src/__support/OSUtil/baremetal/quick_exit.h)13
-rw-r--r--src/__support/OSUtil/darwin/quick_exit.h26
-rw-r--r--src/__support/OSUtil/gpu/io.h2
-rw-r--r--src/__support/OSUtil/gpu/quick_exit.cpp9
-rw-r--r--src/__support/OSUtil/linux/quick_exit.cpp (renamed from src/__support/OSUtil/linux/quick_exit.h)11
-rw-r--r--src/__support/OSUtil/quick_exit.h15
-rw-r--r--src/__support/RPC/rpc.h187
-rw-r--r--src/__support/RPC/rpc_client.h2
-rw-r--r--src/__support/RPC/rpc_util.h22
-rw-r--r--src/__support/StringUtil/message_mapper.h6
-rw-r--r--src/__support/StringUtil/platform_errors.h6
-rw-r--r--src/__support/StringUtil/platform_signals.h6
-rw-r--r--src/__support/StringUtil/tables/linux_extension_errors.h6
-rw-r--r--src/__support/StringUtil/tables/linux_extension_signals.h6
-rw-r--r--src/__support/StringUtil/tables/linux_platform_errors.h6
-rw-r--r--src/__support/StringUtil/tables/linux_platform_signals.h6
-rw-r--r--src/__support/StringUtil/tables/minimal_platform_errors.h6
-rw-r--r--src/__support/StringUtil/tables/minimal_platform_signals.h6
-rw-r--r--src/__support/StringUtil/tables/posix_errors.h6
-rw-r--r--src/__support/StringUtil/tables/posix_signals.h6
-rw-r--r--src/__support/StringUtil/tables/signal_table.h6
-rw-r--r--src/__support/StringUtil/tables/stdc_errors.h6
-rw-r--r--src/__support/StringUtil/tables/stdc_signals.h6
-rw-r--r--src/__support/UInt.h1716
-rw-r--r--src/__support/UInt128.h9
-rw-r--r--src/__support/arg_list.h38
-rw-r--r--src/__support/blockstore.h32
-rw-r--r--src/__support/char_vector.h8
-rw-r--r--src/__support/fixed_point/fx_bits.h168
-rw-r--r--src/__support/fixed_point/fx_rep.h300
-rw-r--r--src/__support/fixed_point/sqrt.h258
-rw-r--r--src/__support/fixedvector.h8
-rw-r--r--src/__support/float_to_string.h109
-rw-r--r--src/__support/high_precision_decimal.h116
-rw-r--r--src/__support/integer_literals.h187
-rw-r--r--src/__support/integer_to_string.h21
-rw-r--r--src/__support/integer_utils.h65
-rw-r--r--src/__support/intrusive_list.h65
-rw-r--r--src/__support/macros/config.h28
-rw-r--r--src/__support/macros/optimization.h1
-rw-r--r--src/__support/macros/properties/float.h83
-rw-r--r--src/__support/macros/properties/types.h69
-rw-r--r--src/__support/macros/sanitizer.h3
-rw-r--r--src/__support/math_extras.h254
-rw-r--r--src/__support/memory_size.h13
-rw-r--r--src/__support/number_pair.h15
-rw-r--r--src/__support/sign.h40
-rw-r--r--src/__support/str_to_float.h88
-rw-r--r--src/__support/str_to_integer.h117
-rw-r--r--src/__support/threads/gpu/mutex.h6
-rw-r--r--src/__support/threads/sleep.h34
-rw-r--r--src/assert/assert.h3
-rw-r--r--src/errno/libc_errno.cpp60
-rw-r--r--src/errno/libc_errno.h59
-rw-r--r--src/gpu/rpc_fprintf.cpp71
-rw-r--r--src/gpu/rpc_fprintf.h22
-rw-r--r--src/gpu/rpc_host_call.h2
-rw-r--r--src/math/amdgpu/acos.cpp18
-rw-r--r--src/math/amdgpu/acosf.cpp18
-rw-r--r--src/math/amdgpu/acosh.cpp18
-rw-r--r--src/math/amdgpu/acoshf.cpp18
-rw-r--r--src/math/amdgpu/asin.cpp18
-rw-r--r--src/math/amdgpu/asinf.cpp18
-rw-r--r--src/math/amdgpu/asinh.cpp18
-rw-r--r--src/math/amdgpu/asinhf.cpp18
-rw-r--r--src/math/amdgpu/atan.cpp18
-rw-r--r--src/math/amdgpu/atan2.cpp20
-rw-r--r--src/math/amdgpu/atan2f.cpp20
-rw-r--r--src/math/amdgpu/atanf.cpp18
-rw-r--r--src/math/amdgpu/atanh.cpp18
-rw-r--r--src/math/amdgpu/atanhf.cpp18
-rw-r--r--src/math/amdgpu/ceil.cpp (renamed from src/math/gpu/ceil.cpp)0
-rw-r--r--src/math/amdgpu/ceilf.cpp (renamed from src/math/gpu/ceilf.cpp)0
-rw-r--r--src/math/amdgpu/copysign.cpp (renamed from src/math/gpu/copysign.cpp)0
-rw-r--r--src/math/amdgpu/copysignf.cpp (renamed from src/math/gpu/copysignf.cpp)0
-rw-r--r--src/math/amdgpu/cos.cpp18
-rw-r--r--src/math/amdgpu/cosf.cpp18
-rw-r--r--src/math/amdgpu/cosh.cpp18
-rw-r--r--src/math/amdgpu/coshf.cpp18
-rw-r--r--src/math/amdgpu/declarations.h (renamed from src/math/gpu/vendor/amdgpu/declarations.h)8
-rw-r--r--src/math/amdgpu/erf.cpp18
-rw-r--r--src/math/amdgpu/erff.cpp18
-rw-r--r--src/math/amdgpu/exp.cpp18
-rw-r--r--src/math/amdgpu/exp10.cpp18
-rw-r--r--src/math/amdgpu/exp10f.cpp18
-rw-r--r--src/math/amdgpu/exp2.cpp18
-rw-r--r--src/math/amdgpu/exp2f.cpp18
-rw-r--r--src/math/amdgpu/expf.cpp18
-rw-r--r--src/math/amdgpu/expm1.cpp18
-rw-r--r--src/math/amdgpu/expm1f.cpp18
-rw-r--r--src/math/amdgpu/fabs.cpp (renamed from src/math/gpu/fabs.cpp)0
-rw-r--r--src/math/amdgpu/fabsf.cpp (renamed from src/math/gpu/fabsf.cpp)0
-rw-r--r--src/math/amdgpu/fdim.cpp20
-rw-r--r--src/math/amdgpu/fdimf.cpp20
-rw-r--r--src/math/amdgpu/floor.cpp (renamed from src/math/gpu/floor.cpp)0
-rw-r--r--src/math/amdgpu/floorf.cpp (renamed from src/math/gpu/floorf.cpp)0
-rw-r--r--src/math/amdgpu/fma.cpp (renamed from src/math/gpu/fma.cpp)0
-rw-r--r--src/math/amdgpu/fmaf.cpp (renamed from src/math/gpu/fmaf.cpp)0
-rw-r--r--src/math/amdgpu/fmax.cpp21
-rw-r--r--src/math/amdgpu/fmaxf.cpp (renamed from src/math/gpu/fmaxf.cpp)1
-rw-r--r--src/math/amdgpu/fmin.cpp (renamed from src/math/gpu/fmin.cpp)1
-rw-r--r--src/math/amdgpu/fminf.cpp (renamed from src/math/gpu/fminf.cpp)1
-rw-r--r--src/math/amdgpu/fmod.cpp (renamed from src/math/gpu/fmod.cpp)0
-rw-r--r--src/math/amdgpu/fmodf.cpp (renamed from src/math/gpu/fmodf.cpp)0
-rw-r--r--src/math/amdgpu/frexp.cpp20
-rw-r--r--src/math/amdgpu/frexpf.cpp20
-rw-r--r--src/math/amdgpu/hypot.cpp20
-rw-r--r--src/math/amdgpu/hypotf.cpp20
-rw-r--r--src/math/amdgpu/ilogb.cpp18
-rw-r--r--src/math/amdgpu/ilogbf.cpp18
-rw-r--r--src/math/amdgpu/ldexp.cpp20
-rw-r--r--src/math/amdgpu/ldexpf.cpp20
-rw-r--r--src/math/amdgpu/llrint.cpp (renamed from src/math/gpu/vendor/llrint.cpp)4
-rw-r--r--src/math/amdgpu/llrintf.cpp (renamed from src/math/gpu/vendor/llrintf.cpp)4
-rw-r--r--src/math/amdgpu/log.cpp18
-rw-r--r--src/math/amdgpu/log10.cpp18
-rw-r--r--src/math/amdgpu/log10f.cpp18
-rw-r--r--src/math/amdgpu/log1p.cpp18
-rw-r--r--src/math/amdgpu/log1pf.cpp18
-rw-r--r--src/math/amdgpu/log2.cpp18
-rw-r--r--src/math/amdgpu/log2f.cpp18
-rw-r--r--src/math/amdgpu/logb.cpp18
-rw-r--r--src/math/amdgpu/logbf.cpp18
-rw-r--r--src/math/amdgpu/logf.cpp18
-rw-r--r--src/math/amdgpu/lrint.cpp20
-rw-r--r--src/math/amdgpu/lrintf.cpp20
-rw-r--r--src/math/amdgpu/nearbyint.cpp (renamed from src/math/gpu/nearbyint.cpp)0
-rw-r--r--src/math/amdgpu/nearbyintf.cpp (renamed from src/math/gpu/nearbyintf.cpp)0
-rw-r--r--src/math/amdgpu/nextafter.cpp20
-rw-r--r--src/math/amdgpu/nextafterf.cpp20
-rw-r--r--src/math/amdgpu/platform.h54
-rw-r--r--src/math/amdgpu/pow.cpp (renamed from src/math/gpu/vendor/pow.cpp)4
-rw-r--r--src/math/amdgpu/powf.cpp (renamed from src/math/gpu/vendor/powf.cpp)4
-rw-r--r--src/math/amdgpu/remainder.cpp (renamed from src/math/gpu/remainder.cpp)0
-rw-r--r--src/math/amdgpu/remainderf.cpp (renamed from src/math/gpu/remainderf.cpp)0
-rw-r--r--src/math/amdgpu/remquo.cpp23
-rw-r--r--src/math/amdgpu/remquof.cpp23
-rw-r--r--src/math/amdgpu/rint.cpp (renamed from src/math/gpu/rint.cpp)0
-rw-r--r--src/math/amdgpu/rintf.cpp (renamed from src/math/gpu/rintf.cpp)0
-rw-r--r--src/math/amdgpu/round.cpp (renamed from src/math/gpu/round.cpp)0
-rw-r--r--src/math/amdgpu/roundf.cpp (renamed from src/math/gpu/roundf.cpp)0
-rw-r--r--src/math/amdgpu/scalbn.cpp20
-rw-r--r--src/math/amdgpu/scalbnf.cpp20
-rw-r--r--src/math/amdgpu/sin.cpp18
-rw-r--r--src/math/amdgpu/sincos.cpp20
-rw-r--r--src/math/amdgpu/sincosf.cpp (renamed from src/math/gpu/vendor/sincosf.cpp)4
-rw-r--r--src/math/amdgpu/sinf.cpp18
-rw-r--r--src/math/amdgpu/sinh.cpp (renamed from src/math/gpu/sinh.cpp)6
-rw-r--r--src/math/amdgpu/sinhf.cpp18
-rw-r--r--src/math/amdgpu/sqrt.cpp (renamed from src/math/gpu/sqrt.cpp)0
-rw-r--r--src/math/amdgpu/sqrtf.cpp (renamed from src/math/gpu/sqrtf.cpp)0
-rw-r--r--src/math/amdgpu/tan.cpp (renamed from src/math/gpu/tan.cpp)6
-rw-r--r--src/math/amdgpu/tanf.cpp18
-rw-r--r--src/math/amdgpu/tanh.cpp (renamed from src/math/gpu/tanh.cpp)6
-rw-r--r--src/math/amdgpu/tanhf.cpp18
-rw-r--r--src/math/amdgpu/tgamma.cpp18
-rw-r--r--src/math/amdgpu/tgammaf.cpp18
-rw-r--r--src/math/amdgpu/trunc.cpp (renamed from src/math/gpu/trunc.cpp)0
-rw-r--r--src/math/amdgpu/truncf.cpp (renamed from src/math/gpu/truncf.cpp)0
-rw-r--r--src/math/canonicalize.h18
-rw-r--r--src/math/canonicalizef.h18
-rw-r--r--src/math/canonicalizef128.h20
-rw-r--r--src/math/canonicalizel.h18
-rw-r--r--src/math/ceilf128.h20
-rw-r--r--src/math/copysignf128.h4
-rw-r--r--src/math/exp2m1f.h18
-rw-r--r--src/math/fabsf128.h2
-rw-r--r--src/math/fdimf128.h20
-rw-r--r--src/math/floorf128.h20
-rw-r--r--src/math/fmaxf128.h2
-rw-r--r--src/math/fmaximum.h19
-rw-r--r--src/math/fmaximum_mag.h19
-rw-r--r--src/math/fmaximum_mag_num.h18
-rw-r--r--src/math/fmaximum_mag_numf.h19
-rw-r--r--src/math/fmaximum_mag_numf128.h21
-rw-r--r--src/math/fmaximum_mag_numl.h19
-rw-r--r--src/math/fmaximum_magf.h19
-rw-r--r--src/math/fmaximum_magf128.h21
-rw-r--r--src/math/fmaximum_magl.h19
-rw-r--r--src/math/fmaximum_num.h19
-rw-r--r--src/math/fmaximum_numf.h19
-rw-r--r--src/math/fmaximum_numf128.h21
-rw-r--r--src/math/fmaximum_numl.h19
-rw-r--r--src/math/fmaximumf.h19
-rw-r--r--src/math/fmaximumf128.h21
-rw-r--r--src/math/fmaximuml.h19
-rw-r--r--src/math/fminf128.h2
-rw-r--r--src/math/fminimum.h19
-rw-r--r--src/math/fminimum_mag.h19
-rw-r--r--src/math/fminimum_mag_num.h19
-rw-r--r--src/math/fminimum_mag_numf.h19
-rw-r--r--src/math/fminimum_mag_numf128.h21
-rw-r--r--src/math/fminimum_mag_numl.h19
-rw-r--r--src/math/fminimum_magf.h19
-rw-r--r--src/math/fminimum_magf128.h21
-rw-r--r--src/math/fminimum_magl.h19
-rw-r--r--src/math/fminimum_num.h19
-rw-r--r--src/math/fminimum_numf.h19
-rw-r--r--src/math/fminimum_numf128.h21
-rw-r--r--src/math/fminimum_numl.h19
-rw-r--r--src/math/fminimumf.h19
-rw-r--r--src/math/fminimumf128.h21
-rw-r--r--src/math/fminimuml.h19
-rw-r--r--src/math/fmodf128.h20
-rw-r--r--src/math/fmodl.h18
-rw-r--r--src/math/frexpf128.h20
-rw-r--r--src/math/fromfp.h18
-rw-r--r--src/math/fromfpf.h18
-rw-r--r--src/math/fromfpf128.h20
-rw-r--r--src/math/fromfpl.h18
-rw-r--r--src/math/fromfpx.h18
-rw-r--r--src/math/fromfpxf.h18
-rw-r--r--src/math/fromfpxf128.h20
-rw-r--r--src/math/fromfpxl.h18
-rw-r--r--src/math/generic/acosf.cpp2
-rw-r--r--src/math/generic/acoshf.cpp6
-rw-r--r--src/math/generic/asinf.cpp2
-rw-r--r--src/math/generic/asinhf.cpp4
-rw-r--r--src/math/generic/atan2f.cpp306
-rw-r--r--src/math/generic/atanf.cpp126
-rw-r--r--src/math/generic/atanhf.cpp2
-rw-r--r--src/math/generic/canonicalize.cpp19
-rw-r--r--src/math/generic/canonicalizef.cpp19
-rw-r--r--src/math/generic/canonicalizef128.cpp19
-rw-r--r--src/math/generic/canonicalizel.cpp20
-rw-r--r--src/math/generic/ceilf128.cpp17
-rw-r--r--src/math/generic/cosf.cpp2
-rw-r--r--src/math/generic/coshf.cpp2
-rw-r--r--src/math/generic/exp.cpp26
-rw-r--r--src/math/generic/exp10.cpp22
-rw-r--r--src/math/generic/exp2.cpp22
-rw-r--r--src/math/generic/exp2m1f.cpp183
-rw-r--r--src/math/generic/exp_utils.h6
-rw-r--r--src/math/generic/expm1.cpp30
-rw-r--r--src/math/generic/fdimf128.cpp19
-rw-r--r--src/math/generic/floorf128.cpp19
-rw-r--r--src/math/generic/fmaximum.cpp19
-rw-r--r--src/math/generic/fmaximum_mag.cpp19
-rw-r--r--src/math/generic/fmaximum_mag_num.cpp19
-rw-r--r--src/math/generic/fmaximum_mag_numf.cpp19
-rw-r--r--src/math/generic/fmaximum_mag_numf128.cpp19
-rw-r--r--src/math/generic/fmaximum_mag_numl.cpp20
-rw-r--r--src/math/generic/fmaximum_magf.cpp19
-rw-r--r--src/math/generic/fmaximum_magf128.cpp19
-rw-r--r--src/math/generic/fmaximum_magl.cpp19
-rw-r--r--src/math/generic/fmaximum_num.cpp19
-rw-r--r--src/math/generic/fmaximum_numf.cpp19
-rw-r--r--src/math/generic/fmaximum_numf128.cpp19
-rw-r--r--src/math/generic/fmaximum_numl.cpp19
-rw-r--r--src/math/generic/fmaximumf.cpp19
-rw-r--r--src/math/generic/fmaximumf128.cpp19
-rw-r--r--src/math/generic/fmaximuml.cpp19
-rw-r--r--src/math/generic/fminimum.cpp19
-rw-r--r--src/math/generic/fminimum_mag.cpp19
-rw-r--r--src/math/generic/fminimum_mag_num.cpp19
-rw-r--r--src/math/generic/fminimum_mag_numf.cpp19
-rw-r--r--src/math/generic/fminimum_mag_numf128.cpp19
-rw-r--r--src/math/generic/fminimum_mag_numl.cpp20
-rw-r--r--src/math/generic/fminimum_magf.cpp19
-rw-r--r--src/math/generic/fminimum_magf128.cpp19
-rw-r--r--src/math/generic/fminimum_magl.cpp19
-rw-r--r--src/math/generic/fminimum_num.cpp19
-rw-r--r--src/math/generic/fminimum_numf.cpp19
-rw-r--r--src/math/generic/fminimum_numf128.cpp19
-rw-r--r--src/math/generic/fminimum_numl.cpp19
-rw-r--r--src/math/generic/fminimumf.cpp19
-rw-r--r--src/math/generic/fminimumf128.cpp19
-rw-r--r--src/math/generic/fminimuml.cpp19
-rw-r--r--src/math/generic/fmodf.cpp2
-rw-r--r--src/math/generic/fmodf128.cpp19
-rw-r--r--src/math/generic/fmodl.cpp19
-rw-r--r--src/math/generic/frexpf128.cpp19
-rw-r--r--src/math/generic/fromfp.cpp19
-rw-r--r--src/math/generic/fromfpf.cpp19
-rw-r--r--src/math/generic/fromfpf128.cpp20
-rw-r--r--src/math/generic/fromfpl.cpp20
-rw-r--r--src/math/generic/fromfpx.cpp19
-rw-r--r--src/math/generic/fromfpxf.cpp19
-rw-r--r--src/math/generic/fromfpxf128.cpp20
-rw-r--r--src/math/generic/fromfpxl.cpp20
-rw-r--r--src/math/generic/hypotf.cpp4
-rw-r--r--src/math/generic/ilogb.cpp2
-rw-r--r--src/math/generic/ilogbf.cpp2
-rw-r--r--src/math/generic/ilogbf128.cpp19
-rw-r--r--src/math/generic/ilogbl.cpp4
-rw-r--r--src/math/generic/inv_trigf_utils.cpp85
-rw-r--r--src/math/generic/inv_trigf_utils.h82
-rw-r--r--src/math/generic/ldexpf128.cpp19
-rw-r--r--src/math/generic/llogb.cpp17
-rw-r--r--src/math/generic/llogbf.cpp17
-rw-r--r--src/math/generic/llogbf128.cpp19
-rw-r--r--src/math/generic/llogbl.cpp19
-rw-r--r--src/math/generic/llrintf128.cpp21
-rw-r--r--src/math/generic/llroundf128.cpp19
-rw-r--r--src/math/generic/log.cpp1269
-rw-r--r--src/math/generic/log10.cpp1274
-rw-r--r--src/math/generic/log10f.cpp2
-rw-r--r--src/math/generic/log1p.cpp958
-rw-r--r--src/math/generic/log1pf.cpp2
-rw-r--r--src/math/generic/log2.cpp1259
-rw-r--r--src/math/generic/log2f.cpp2
-rw-r--r--src/math/generic/log_range_reduction.h1
-rw-r--r--src/math/generic/logbf.cpp2
-rw-r--r--src/math/generic/logbf128.cpp17
-rw-r--r--src/math/generic/logf.cpp2
-rw-r--r--src/math/generic/lrintf128.cpp20
-rw-r--r--src/math/generic/lroundf128.cpp19
-rw-r--r--src/math/generic/math_utils.h3
-rw-r--r--src/math/generic/modff128.cpp19
-rw-r--r--src/math/generic/nanf128.cpp23
-rw-r--r--src/math/generic/nextafterf128.cpp19
-rw-r--r--src/math/generic/nextdown.cpp19
-rw-r--r--src/math/generic/nextdownf.cpp19
-rw-r--r--src/math/generic/nextdownf128.cpp19
-rw-r--r--src/math/generic/nextdownl.cpp19
-rw-r--r--src/math/generic/nextup.cpp19
-rw-r--r--src/math/generic/nextupf.cpp19
-rw-r--r--src/math/generic/nextupf128.cpp19
-rw-r--r--src/math/generic/nextupl.cpp19
-rw-r--r--src/math/generic/powf.cpp4
-rw-r--r--src/math/generic/rintf128.cpp19
-rw-r--r--src/math/generic/roundeven.cpp19
-rw-r--r--src/math/generic/roundevenf.cpp19
-rw-r--r--src/math/generic/roundevenf128.cpp19
-rw-r--r--src/math/generic/roundevenl.cpp19
-rw-r--r--src/math/generic/roundf128.cpp19
-rw-r--r--src/math/generic/truncf128.cpp19
-rw-r--r--src/math/generic/ufromfp.cpp19
-rw-r--r--src/math/generic/ufromfpf.cpp19
-rw-r--r--src/math/generic/ufromfpf128.cpp20
-rw-r--r--src/math/generic/ufromfpl.cpp20
-rw-r--r--src/math/generic/ufromfpx.cpp19
-rw-r--r--src/math/generic/ufromfpxf.cpp19
-rw-r--r--src/math/generic/ufromfpxf128.cpp20
-rw-r--r--src/math/generic/ufromfpxl.cpp20
-rw-r--r--src/math/gpu/llround.cpp18
-rw-r--r--src/math/gpu/llroundf.cpp18
-rw-r--r--src/math/gpu/lround.cpp16
-rw-r--r--src/math/gpu/lroundf.cpp16
-rw-r--r--src/math/gpu/modf.cpp18
-rw-r--r--src/math/gpu/modff.cpp18
-rw-r--r--src/math/gpu/vendor/amdgpu/amdgpu.h127
-rw-r--r--src/math/gpu/vendor/amdgpu/platform.h130
-rw-r--r--src/math/gpu/vendor/common.h22
-rw-r--r--src/math/ilogbf128.h20
-rw-r--r--src/math/ldexpf128.h20
-rw-r--r--src/math/llogb.h20
-rw-r--r--src/math/llogbf.h20
-rw-r--r--src/math/llogbf128.h20
-rw-r--r--src/math/llogbl.h20
-rw-r--r--src/math/llrintf128.h20
-rw-r--r--src/math/llroundf128.h20
-rw-r--r--src/math/logbf128.h20
-rw-r--r--src/math/lrintf128.h20
-rw-r--r--src/math/lroundf128.h20
-rw-r--r--src/math/modff128.h20
-rw-r--r--src/math/nanf128.h20
-rw-r--r--src/math/nextafterf128.h20
-rw-r--r--src/math/nextdown.h18
-rw-r--r--src/math/nextdownf.h18
-rw-r--r--src/math/nextdownf128.h20
-rw-r--r--src/math/nextdownl.h18
-rw-r--r--src/math/nextup.h18
-rw-r--r--src/math/nextupf.h18
-rw-r--r--src/math/nextupf128.h20
-rw-r--r--src/math/nextupl.h18
-rw-r--r--src/math/nvptx/acos.cpp (renamed from src/math/gpu/vendor/acos.cpp)4
-rw-r--r--src/math/nvptx/acosf.cpp (renamed from src/math/gpu/vendor/acosf.cpp)4
-rw-r--r--src/math/nvptx/acosh.cpp (renamed from src/math/gpu/vendor/acosh.cpp)4
-rw-r--r--src/math/nvptx/acoshf.cpp (renamed from src/math/gpu/vendor/acoshf.cpp)4
-rw-r--r--src/math/nvptx/asin.cpp (renamed from src/math/gpu/vendor/asin.cpp)4
-rw-r--r--src/math/nvptx/asinf.cpp (renamed from src/math/gpu/vendor/asinf.cpp)4
-rw-r--r--src/math/nvptx/asinh.cpp (renamed from src/math/gpu/vendor/asinh.cpp)4
-rw-r--r--src/math/nvptx/asinhf.cpp (renamed from src/math/gpu/vendor/asinhf.cpp)4
-rw-r--r--src/math/nvptx/atan.cpp (renamed from src/math/gpu/vendor/atan.cpp)4
-rw-r--r--src/math/nvptx/atan2.cpp (renamed from src/math/gpu/vendor/atan2.cpp)4
-rw-r--r--src/math/nvptx/atan2f.cpp (renamed from src/math/gpu/vendor/atan2f.cpp)4
-rw-r--r--src/math/nvptx/atanf.cpp (renamed from src/math/gpu/vendor/atanf.cpp)4
-rw-r--r--src/math/nvptx/atanh.cpp (renamed from src/math/gpu/vendor/atanh.cpp)4
-rw-r--r--src/math/nvptx/atanhf.cpp (renamed from src/math/gpu/vendor/atanhf.cpp)4
-rw-r--r--src/math/nvptx/ceil.cpp16
-rw-r--r--src/math/nvptx/ceilf.cpp16
-rw-r--r--src/math/nvptx/copysign.cpp18
-rw-r--r--src/math/nvptx/copysignf.cpp18
-rw-r--r--src/math/nvptx/cos.cpp (renamed from src/math/gpu/vendor/cos.cpp)4
-rw-r--r--src/math/nvptx/cosf.cpp (renamed from src/math/gpu/vendor/cosf.cpp)4
-rw-r--r--src/math/nvptx/cosh.cpp (renamed from src/math/gpu/vendor/cosh.cpp)4
-rw-r--r--src/math/nvptx/coshf.cpp (renamed from src/math/gpu/vendor/coshf.cpp)4
-rw-r--r--src/math/nvptx/declarations.h (renamed from src/math/gpu/vendor/nvptx/declarations.h)6
-rw-r--r--src/math/nvptx/erf.cpp (renamed from src/math/gpu/vendor/erf.cpp)4
-rw-r--r--src/math/nvptx/erff.cpp (renamed from src/math/gpu/vendor/erff.cpp)4
-rw-r--r--src/math/nvptx/exp.cpp (renamed from src/math/gpu/vendor/exp.cpp)4
-rw-r--r--src/math/nvptx/exp10.cpp (renamed from src/math/gpu/vendor/exp10.cpp)4
-rw-r--r--src/math/nvptx/exp10f.cpp (renamed from src/math/gpu/vendor/exp10f.cpp)4
-rw-r--r--src/math/nvptx/exp2.cpp (renamed from src/math/gpu/vendor/exp2.cpp)4
-rw-r--r--src/math/nvptx/exp2f.cpp (renamed from src/math/gpu/vendor/exp2f.cpp)4
-rw-r--r--src/math/nvptx/expf.cpp (renamed from src/math/gpu/vendor/expf.cpp)4
-rw-r--r--src/math/nvptx/expm1.cpp (renamed from src/math/gpu/vendor/expm1.cpp)4
-rw-r--r--src/math/nvptx/expm1f.cpp (renamed from src/math/gpu/vendor/expm1f.cpp)4
-rw-r--r--src/math/nvptx/fabs.cpp16
-rw-r--r--src/math/nvptx/fabsf.cpp16
-rw-r--r--src/math/nvptx/fdim.cpp (renamed from src/math/gpu/vendor/fdim.cpp)4
-rw-r--r--src/math/nvptx/fdimf.cpp (renamed from src/math/gpu/vendor/fdimf.cpp)4
-rw-r--r--src/math/nvptx/floor.cpp16
-rw-r--r--src/math/nvptx/floorf.cpp16
-rw-r--r--src/math/nvptx/fma.cpp18
-rw-r--r--src/math/nvptx/fmaf.cpp18
-rw-r--r--src/math/nvptx/fmax.cpp (renamed from src/math/gpu/fmax.cpp)1
-rw-r--r--src/math/nvptx/fmaxf.cpp21
-rw-r--r--src/math/nvptx/fmin.cpp19
-rw-r--r--src/math/nvptx/fminf.cpp19
-rw-r--r--src/math/nvptx/fmod.cpp18
-rw-r--r--src/math/nvptx/fmodf.cpp18
-rw-r--r--src/math/nvptx/frexp.cpp (renamed from src/math/gpu/vendor/frexp.cpp)4
-rw-r--r--src/math/nvptx/frexpf.cpp (renamed from src/math/gpu/vendor/frexpf.cpp)4
-rw-r--r--src/math/nvptx/hypot.cpp (renamed from src/math/gpu/vendor/hypot.cpp)4
-rw-r--r--src/math/nvptx/hypotf.cpp (renamed from src/math/gpu/vendor/hypotf.cpp)4
-rw-r--r--src/math/nvptx/ilogb.cpp (renamed from src/math/gpu/vendor/ilogb.cpp)4
-rw-r--r--src/math/nvptx/ilogbf.cpp (renamed from src/math/gpu/vendor/ilogbf.cpp)4
-rw-r--r--src/math/nvptx/ldexp.cpp (renamed from src/math/gpu/vendor/ldexp.cpp)4
-rw-r--r--src/math/nvptx/ldexpf.cpp (renamed from src/math/gpu/vendor/ldexpf.cpp)4
-rw-r--r--src/math/nvptx/llrint.cpp18
-rw-r--r--src/math/nvptx/llrintf.cpp18
-rw-r--r--src/math/nvptx/log.cpp (renamed from src/math/gpu/vendor/log.cpp)4
-rw-r--r--src/math/nvptx/log10.cpp (renamed from src/math/gpu/vendor/log10.cpp)4
-rw-r--r--src/math/nvptx/log10f.cpp (renamed from src/math/gpu/vendor/log10f.cpp)4
-rw-r--r--src/math/nvptx/log1p.cpp (renamed from src/math/gpu/vendor/log1p.cpp)4
-rw-r--r--src/math/nvptx/log1pf.cpp (renamed from src/math/gpu/vendor/log1pf.cpp)4
-rw-r--r--src/math/nvptx/log2.cpp (renamed from src/math/gpu/vendor/log2.cpp)4
-rw-r--r--src/math/nvptx/log2f.cpp (renamed from src/math/gpu/vendor/log2f.cpp)4
-rw-r--r--src/math/nvptx/logb.cpp (renamed from src/math/gpu/vendor/logb.cpp)4
-rw-r--r--src/math/nvptx/logbf.cpp (renamed from src/math/gpu/vendor/logbf.cpp)4
-rw-r--r--src/math/nvptx/logf.cpp (renamed from src/math/gpu/vendor/logf.cpp)4
-rw-r--r--src/math/nvptx/lrint.cpp (renamed from src/math/gpu/vendor/lrint.cpp)4
-rw-r--r--src/math/nvptx/lrintf.cpp (renamed from src/math/gpu/vendor/lrintf.cpp)4
-rw-r--r--src/math/nvptx/nearbyint.cpp18
-rw-r--r--src/math/nvptx/nearbyintf.cpp18
-rw-r--r--src/math/nvptx/nextafter.cpp (renamed from src/math/gpu/vendor/nextafter.cpp)4
-rw-r--r--src/math/nvptx/nextafterf.cpp (renamed from src/math/gpu/vendor/nextafterf.cpp)4
-rw-r--r--src/math/nvptx/nvptx.h (renamed from src/math/gpu/vendor/nvptx/nvptx.h)6
-rw-r--r--src/math/nvptx/pow.cpp18
-rw-r--r--src/math/nvptx/powf.cpp18
-rw-r--r--src/math/nvptx/remainder.cpp18
-rw-r--r--src/math/nvptx/remainderf.cpp18
-rw-r--r--src/math/nvptx/remquo.cpp (renamed from src/math/gpu/vendor/remquo.cpp)4
-rw-r--r--src/math/nvptx/remquof.cpp (renamed from src/math/gpu/vendor/remquof.cpp)4
-rw-r--r--src/math/nvptx/rint.cpp16
-rw-r--r--src/math/nvptx/rintf.cpp16
-rw-r--r--src/math/nvptx/round.cpp16
-rw-r--r--src/math/nvptx/roundf.cpp16
-rw-r--r--src/math/nvptx/scalbn.cpp (renamed from src/math/gpu/vendor/scalbn.cpp)4
-rw-r--r--src/math/nvptx/scalbnf.cpp (renamed from src/math/gpu/vendor/scalbnf.cpp)4
-rw-r--r--src/math/nvptx/sin.cpp (renamed from src/math/gpu/vendor/sin.cpp)4
-rw-r--r--src/math/nvptx/sincos.cpp (renamed from src/math/gpu/vendor/sincos.cpp)4
-rw-r--r--src/math/nvptx/sincosf.cpp20
-rw-r--r--src/math/nvptx/sinf.cpp (renamed from src/math/gpu/vendor/sinf.cpp)4
-rw-r--r--src/math/nvptx/sinh.cpp (renamed from src/math/gpu/vendor/sinh.cpp)4
-rw-r--r--src/math/nvptx/sinhf.cpp (renamed from src/math/gpu/vendor/sinhf.cpp)4
-rw-r--r--src/math/nvptx/sqrt.cpp16
-rw-r--r--src/math/nvptx/sqrtf.cpp16
-rw-r--r--src/math/nvptx/tan.cpp (renamed from src/math/gpu/vendor/tan.cpp)4
-rw-r--r--src/math/nvptx/tanf.cpp (renamed from src/math/gpu/vendor/tanf.cpp)4
-rw-r--r--src/math/nvptx/tanh.cpp (renamed from src/math/gpu/vendor/tanh.cpp)4
-rw-r--r--src/math/nvptx/tanhf.cpp (renamed from src/math/gpu/vendor/tanhf.cpp)4
-rw-r--r--src/math/nvptx/tgamma.cpp (renamed from src/math/gpu/vendor/tgamma.cpp)4
-rw-r--r--src/math/nvptx/tgammaf.cpp (renamed from src/math/gpu/vendor/tgammaf.cpp)4
-rw-r--r--src/math/nvptx/trunc.cpp16
-rw-r--r--src/math/nvptx/truncf.cpp16
-rw-r--r--src/math/rintf128.h20
-rw-r--r--src/math/roundeven.h18
-rw-r--r--src/math/roundevenf.h18
-rw-r--r--src/math/roundevenf128.h20
-rw-r--r--src/math/roundevenl.h18
-rw-r--r--src/math/roundf128.h20
-rw-r--r--src/math/sqrtf128.h2
-rw-r--r--src/math/truncf128.h20
-rw-r--r--src/math/ufromfp.h18
-rw-r--r--src/math/ufromfpf.h18
-rw-r--r--src/math/ufromfpf128.h20
-rw-r--r--src/math/ufromfpl.h18
-rw-r--r--src/math/ufromfpx.h18
-rw-r--r--src/math/ufromfpxf.h18
-rw-r--r--src/math/ufromfpxf128.h20
-rw-r--r--src/math/ufromfpxl.h18
-rw-r--r--src/search/hsearch/global.h5
-rw-r--r--src/search/insque.cpp19
-rw-r--r--src/search/insque.h20
-rw-r--r--src/search/remque.cpp19
-rw-r--r--src/search/remque.h20
-rw-r--r--src/stdbit/stdc_bit_ceil_uc.cpp20
-rw-r--r--src/stdbit/stdc_bit_ceil_uc.h18
-rw-r--r--src/stdbit/stdc_bit_ceil_ui.cpp20
-rw-r--r--src/stdbit/stdc_bit_ceil_ui.h18
-rw-r--r--src/stdbit/stdc_bit_ceil_ul.cpp20
-rw-r--r--src/stdbit/stdc_bit_ceil_ul.h18
-rw-r--r--src/stdbit/stdc_bit_ceil_ull.cpp21
-rw-r--r--src/stdbit/stdc_bit_ceil_ull.h18
-rw-r--r--src/stdbit/stdc_bit_ceil_us.cpp20
-rw-r--r--src/stdbit/stdc_bit_ceil_us.h18
-rw-r--r--src/stdbit/stdc_bit_floor_uc.cpp20
-rw-r--r--src/stdbit/stdc_bit_floor_uc.h18
-rw-r--r--src/stdbit/stdc_bit_floor_ui.cpp20
-rw-r--r--src/stdbit/stdc_bit_floor_ui.h18
-rw-r--r--src/stdbit/stdc_bit_floor_ul.cpp20
-rw-r--r--src/stdbit/stdc_bit_floor_ul.h18
-rw-r--r--src/stdbit/stdc_bit_floor_ull.cpp21
-rw-r--r--src/stdbit/stdc_bit_floor_ull.h18
-rw-r--r--src/stdbit/stdc_bit_floor_us.cpp20
-rw-r--r--src/stdbit/stdc_bit_floor_us.h18
-rw-r--r--src/stdbit/stdc_bit_width_uc.cpp20
-rw-r--r--src/stdbit/stdc_bit_width_uc.h18
-rw-r--r--src/stdbit/stdc_bit_width_ui.cpp20
-rw-r--r--src/stdbit/stdc_bit_width_ui.h18
-rw-r--r--src/stdbit/stdc_bit_width_ul.cpp20
-rw-r--r--src/stdbit/stdc_bit_width_ul.h18
-rw-r--r--src/stdbit/stdc_bit_width_ull.cpp20
-rw-r--r--src/stdbit/stdc_bit_width_ull.h18
-rw-r--r--src/stdbit/stdc_bit_width_us.cpp20
-rw-r--r--src/stdbit/stdc_bit_width_us.h18
-rw-r--r--src/stdbit/stdc_count_ones_uc.cpp20
-rw-r--r--src/stdbit/stdc_count_ones_uc.h18
-rw-r--r--src/stdbit/stdc_count_ones_ui.cpp20
-rw-r--r--src/stdbit/stdc_count_ones_ui.h18
-rw-r--r--src/stdbit/stdc_count_ones_ul.cpp20
-rw-r--r--src/stdbit/stdc_count_ones_ul.h (renamed from src/__support/OSUtil/gpu/quick_exit.h)10
-rw-r--r--src/stdbit/stdc_count_ones_ull.cpp20
-rw-r--r--src/stdbit/stdc_count_ones_ull.h18
-rw-r--r--src/stdbit/stdc_count_ones_us.cpp20
-rw-r--r--src/stdbit/stdc_count_ones_us.h18
-rw-r--r--src/stdbit/stdc_count_zeros_uc.cpp20
-rw-r--r--src/stdbit/stdc_count_zeros_uc.h18
-rw-r--r--src/stdbit/stdc_count_zeros_ui.cpp20
-rw-r--r--src/stdbit/stdc_count_zeros_ui.h18
-rw-r--r--src/stdbit/stdc_count_zeros_ul.cpp20
-rw-r--r--src/stdbit/stdc_count_zeros_ul.h18
-rw-r--r--src/stdbit/stdc_count_zeros_ull.cpp20
-rw-r--r--src/stdbit/stdc_count_zeros_ull.h18
-rw-r--r--src/stdbit/stdc_count_zeros_us.cpp20
-rw-r--r--src/stdbit/stdc_count_zeros_us.h18
-rw-r--r--src/stdbit/stdc_first_leading_one_uc.cpp20
-rw-r--r--src/stdbit/stdc_first_leading_one_uc.h18
-rw-r--r--src/stdbit/stdc_first_leading_one_ui.cpp20
-rw-r--r--src/stdbit/stdc_first_leading_one_ui.h18
-rw-r--r--src/stdbit/stdc_first_leading_one_ul.cpp20
-rw-r--r--src/stdbit/stdc_first_leading_one_ul.h18
-rw-r--r--src/stdbit/stdc_first_leading_one_ull.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_one_ull.h18
-rw-r--r--src/stdbit/stdc_first_leading_one_us.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_one_us.h18
-rw-r--r--src/stdbit/stdc_first_leading_zero_uc.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_zero_uc.h18
-rw-r--r--src/stdbit/stdc_first_leading_zero_ui.cpp20
-rw-r--r--src/stdbit/stdc_first_leading_zero_ui.h18
-rw-r--r--src/stdbit/stdc_first_leading_zero_ul.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_zero_ul.h18
-rw-r--r--src/stdbit/stdc_first_leading_zero_ull.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_zero_ull.h18
-rw-r--r--src/stdbit/stdc_first_leading_zero_us.cpp21
-rw-r--r--src/stdbit/stdc_first_leading_zero_us.h18
-rw-r--r--src/stdbit/stdc_first_trailing_one_uc.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_one_uc.h18
-rw-r--r--src/stdbit/stdc_first_trailing_one_ui.cpp20
-rw-r--r--src/stdbit/stdc_first_trailing_one_ui.h18
-rw-r--r--src/stdbit/stdc_first_trailing_one_ul.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_one_ul.h18
-rw-r--r--src/stdbit/stdc_first_trailing_one_ull.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_one_ull.h18
-rw-r--r--src/stdbit/stdc_first_trailing_one_us.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_one_us.h18
-rw-r--r--src/stdbit/stdc_first_trailing_zero_uc.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_zero_uc.h18
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ui.cpp20
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ui.h18
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ul.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ul.h18
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ull.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_zero_ull.h18
-rw-r--r--src/stdbit/stdc_first_trailing_zero_us.cpp21
-rw-r--r--src/stdbit/stdc_first_trailing_zero_us.h18
-rw-r--r--src/stdbit/stdc_has_single_bit_uc.cpp20
-rw-r--r--src/stdbit/stdc_has_single_bit_uc.h18
-rw-r--r--src/stdbit/stdc_has_single_bit_ui.cpp20
-rw-r--r--src/stdbit/stdc_has_single_bit_ui.h18
-rw-r--r--src/stdbit/stdc_has_single_bit_ul.cpp20
-rw-r--r--src/stdbit/stdc_has_single_bit_ul.h18
-rw-r--r--src/stdbit/stdc_has_single_bit_ull.cpp20
-rw-r--r--src/stdbit/stdc_has_single_bit_ull.h18
-rw-r--r--src/stdbit/stdc_has_single_bit_us.cpp20
-rw-r--r--src/stdbit/stdc_has_single_bit_us.h18
-rw-r--r--src/stdbit/stdc_leading_ones_uc.cpp20
-rw-r--r--src/stdbit/stdc_leading_ones_uc.h18
-rw-r--r--src/stdbit/stdc_leading_ones_ui.cpp20
-rw-r--r--src/stdbit/stdc_leading_ones_ui.h18
-rw-r--r--src/stdbit/stdc_leading_ones_ul.cpp20
-rw-r--r--src/stdbit/stdc_leading_ones_ul.h18
-rw-r--r--src/stdbit/stdc_leading_ones_ull.cpp21
-rw-r--r--src/stdbit/stdc_leading_ones_ull.h18
-rw-r--r--src/stdbit/stdc_leading_ones_us.cpp20
-rw-r--r--src/stdbit/stdc_leading_ones_us.h18
-rw-r--r--src/stdbit/stdc_leading_zeros_uc.cpp5
-rw-r--r--src/stdbit/stdc_leading_zeros_uc.h2
-rw-r--r--src/stdbit/stdc_leading_zeros_ul.cpp5
-rw-r--r--src/stdbit/stdc_leading_zeros_ul.h2
-rw-r--r--src/stdbit/stdc_leading_zeros_ull.cpp4
-rw-r--r--src/stdbit/stdc_leading_zeros_ull.h2
-rw-r--r--src/stdbit/stdc_leading_zeros_us.cpp5
-rw-r--r--src/stdbit/stdc_leading_zeros_us.h2
-rw-r--r--src/stdbit/stdc_trailing_ones_uc.cpp20
-rw-r--r--src/stdbit/stdc_trailing_ones_uc.h18
-rw-r--r--src/stdbit/stdc_trailing_ones_ui.cpp20
-rw-r--r--src/stdbit/stdc_trailing_ones_ui.h18
-rw-r--r--src/stdbit/stdc_trailing_ones_ul.cpp20
-rw-r--r--src/stdbit/stdc_trailing_ones_ul.h18
-rw-r--r--src/stdbit/stdc_trailing_ones_ull.cpp21
-rw-r--r--src/stdbit/stdc_trailing_ones_ull.h18
-rw-r--r--src/stdbit/stdc_trailing_ones_us.cpp20
-rw-r--r--src/stdbit/stdc_trailing_ones_us.h18
-rw-r--r--src/stdbit/stdc_trailing_zeros_uc.cpp20
-rw-r--r--src/stdbit/stdc_trailing_zeros_uc.h18
-rw-r--r--src/stdbit/stdc_trailing_zeros_ui.cpp20
-rw-r--r--src/stdbit/stdc_trailing_zeros_ui.h18
-rw-r--r--src/stdbit/stdc_trailing_zeros_ul.cpp20
-rw-r--r--src/stdbit/stdc_trailing_zeros_ul.h18
-rw-r--r--src/stdbit/stdc_trailing_zeros_ull.cpp21
-rw-r--r--src/stdbit/stdc_trailing_zeros_ull.h18
-rw-r--r--src/stdbit/stdc_trailing_zeros_us.cpp20
-rw-r--r--src/stdbit/stdc_trailing_zeros_us.h18
-rw-r--r--src/stdfix/abshk.cpp19
-rw-r--r--src/stdfix/abshk.h20
-rw-r--r--src/stdfix/abshr.cpp19
-rw-r--r--src/stdfix/abshr.h20
-rw-r--r--src/stdfix/absk.cpp17
-rw-r--r--src/stdfix/absk.h20
-rw-r--r--src/stdfix/abslk.cpp19
-rw-r--r--src/stdfix/abslk.h20
-rw-r--r--src/stdfix/abslr.cpp19
-rw-r--r--src/stdfix/abslr.h20
-rw-r--r--src/stdfix/absr.cpp17
-rw-r--r--src/stdfix/absr.h20
-rw-r--r--src/stdfix/exphk.cpp92
-rw-r--r--src/stdfix/exphk.h20
-rw-r--r--src/stdfix/expk.cpp104
-rw-r--r--src/stdfix/expk.h20
-rw-r--r--src/stdfix/roundhk.cpp19
-rw-r--r--src/stdfix/roundhk.h20
-rw-r--r--src/stdfix/roundhr.cpp19
-rw-r--r--src/stdfix/roundhr.h20
-rw-r--r--src/stdfix/roundk.cpp19
-rw-r--r--src/stdfix/roundk.h20
-rw-r--r--src/stdfix/roundlk.cpp19
-rw-r--r--src/stdfix/roundlk.h20
-rw-r--r--src/stdfix/roundlr.cpp19
-rw-r--r--src/stdfix/roundlr.h20
-rw-r--r--src/stdfix/roundr.cpp19
-rw-r--r--src/stdfix/roundr.h20
-rw-r--r--src/stdfix/rounduhk.cpp20
-rw-r--r--src/stdfix/rounduhk.h20
-rw-r--r--src/stdfix/rounduhr.cpp20
-rw-r--r--src/stdfix/rounduhr.h20
-rw-r--r--src/stdfix/rounduk.cpp19
-rw-r--r--src/stdfix/rounduk.h20
-rw-r--r--src/stdfix/roundulk.cpp20
-rw-r--r--src/stdfix/roundulk.h20
-rw-r--r--src/stdfix/roundulr.cpp20
-rw-r--r--src/stdfix/roundulr.h20
-rw-r--r--src/stdfix/roundur.cpp19
-rw-r--r--src/stdfix/roundur.h20
-rw-r--r--src/stdfix/sqrtuhk.cpp19
-rw-r--r--src/stdfix/sqrtuhk.h20
-rw-r--r--src/stdfix/sqrtuhr.cpp19
-rw-r--r--src/stdfix/sqrtuhr.h20
-rw-r--r--src/stdfix/sqrtuk.cpp19
-rw-r--r--src/stdfix/sqrtuk.h20
-rw-r--r--src/stdfix/sqrtulr.cpp19
-rw-r--r--src/stdfix/sqrtulr.h20
-rw-r--r--src/stdfix/sqrtur.cpp19
-rw-r--r--src/stdfix/sqrtur.h20
-rw-r--r--src/stdfix/uhksqrtus.cpp23
-rw-r--r--src/stdfix/uhksqrtus.h20
-rw-r--r--src/stdfix/uksqrtui.cpp23
-rw-r--r--src/stdfix/uksqrtui.h20
-rw-r--r--src/stdio/baremetal/remove.cpp19
-rw-r--r--src/stdio/fileno.h21
-rw-r--r--src/stdio/fseeko.h21
-rw-r--r--src/stdio/ftello.h21
-rw-r--r--src/stdio/generic/fileno.cpp21
-rw-r--r--src/stdio/generic/fseek.cpp1
-rw-r--r--src/stdio/generic/fseeko.cpp26
-rw-r--r--src/stdio/generic/ftell.cpp1
-rw-r--r--src/stdio/generic/ftello.cpp25
-rw-r--r--src/stdio/linux/rename.cpp28
-rw-r--r--src/stdio/printf_core/converter.cpp10
-rw-r--r--src/stdio/printf_core/converter_atlas.h5
-rw-r--r--src/stdio/printf_core/converter_utils.h19
-rw-r--r--src/stdio/printf_core/core_structs.h35
-rw-r--r--src/stdio/printf_core/fixed_converter.h309
-rw-r--r--src/stdio/printf_core/float_dec_converter.h12
-rw-r--r--src/stdio/printf_core/int_converter.h27
-rw-r--r--src/stdio/printf_core/parser.h139
-rw-r--r--src/stdio/printf_core/printf_config.h7
-rw-r--r--src/stdio/printf_core/string_converter.h2
-rw-r--r--src/stdio/printf_core/write_int_converter.h2
-rw-r--r--src/stdio/rename.h18
-rw-r--r--src/stdio/scanf_core/float_converter.cpp8
-rw-r--r--src/stdlib/_Exit.cpp3
-rw-r--r--src/stdlib/atexit.cpp42
-rw-r--r--src/stdlib/exit.cpp11
-rw-r--r--src/stdlib/gpu/free.cpp11
-rw-r--r--src/stdlib/gpu/malloc.cpp12
-rw-r--r--src/stdlib/str_from_util.h138
-rw-r--r--src/stdlib/strfromd.cpp39
-rw-r--r--src/stdlib/strfromd.h21
-rw-r--r--src/stdlib/strfromf.cpp39
-rw-r--r--src/stdlib/strfromf.h21
-rw-r--r--src/stdlib/strfroml.cpp44
-rw-r--r--src/stdlib/strfroml.h21
-rw-r--r--src/stdlib/strtod.cpp2
-rw-r--r--src/stdlib/strtof.cpp2
-rw-r--r--src/stdlib/strtold.cpp2
-rw-r--r--src/string/memory_utils/aarch64/inline_bcmp.h2
-rw-r--r--src/string/memory_utils/aarch64/inline_memcmp.h2
-rw-r--r--src/string/memory_utils/aarch64/inline_memcpy.h6
-rw-r--r--src/string/memory_utils/generic/aligned_access.h4
-rw-r--r--src/string/memory_utils/generic/builtin.h8
-rw-r--r--src/string/memory_utils/generic/byte_per_byte.h6
-rw-r--r--src/string/memory_utils/op_aarch64.h10
-rw-r--r--src/string/memory_utils/op_builtin.h16
-rw-r--r--src/string/memory_utils/op_generic.h58
-rw-r--r--src/string/memory_utils/op_x86.h12
-rw-r--r--src/string/memory_utils/riscv/inline_memmove.h6
-rw-r--r--src/string/memory_utils/utils.h36
-rw-r--r--src/string/memory_utils/x86_64/inline_bcmp.h2
-rw-r--r--src/string/memory_utils/x86_64/inline_memcmp.h2
-rw-r--r--src/string/memory_utils/x86_64/inline_memcpy.h80
-rw-r--r--src/string/memory_utils/x86_64/inline_memset.h22
-rw-r--r--src/string/memset_explicit.cpp25
-rw-r--r--src/string/memset_explicit.h20
-rw-r--r--src/sys/epoll/epoll_pwait.h26
-rw-r--r--src/sys/epoll/epoll_pwait2.h27
-rw-r--r--src/sys/epoll/epoll_wait.h23
-rw-r--r--src/sys/epoll/linux/epoll_pwait.cpp42
-rw-r--r--src/sys/epoll/linux/epoll_pwait2.cpp44
-rw-r--r--src/sys/epoll/linux/epoll_wait.cpp47
-rw-r--r--src/sys/mman/linux/mlock.cpp26
-rw-r--r--src/sys/mman/linux/mlock2.cpp27
-rw-r--r--src/sys/mman/linux/mlockall.cpp27
-rw-r--r--src/sys/mman/linux/msync.cpp25
-rw-r--r--src/sys/mman/linux/munlock.cpp27
-rw-r--r--src/sys/mman/linux/munlockall.cpp27
-rw-r--r--src/sys/mman/linux/shm_common.h53
-rw-r--r--src/sys/mman/linux/shm_open.cpp25
-rw-r--r--src/sys/mman/linux/shm_unlink.cpp22
-rw-r--r--src/sys/mman/mlock.h21
-rw-r--r--src/sys/mman/mlock2.h23
-rw-r--r--src/sys/mman/mlockall.h20
-rw-r--r--src/sys/mman/msync.h21
-rw-r--r--src/sys/mman/munlock.h20
-rw-r--r--src/sys/mman/munlockall.h20
-rw-r--r--src/sys/mman/shm_open.h20
-rw-r--r--src/sys/mman/shm_unlink.h18
-rw-r--r--src/sys/statvfs/fstatvfs.h20
-rw-r--r--src/sys/statvfs/linux/fstatvfs.cpp26
-rw-r--r--src/sys/statvfs/linux/statfs_utils.h95
-rw-r--r--src/sys/statvfs/linux/statvfs.cpp28
-rw-r--r--src/sys/statvfs/statvfs.h20
-rw-r--r--src/time/gpu/nanosleep.cpp20
-rw-r--r--src/time/gpu/time_utils.h21
-rw-r--r--src/unistd/_exit.cpp19
-rw-r--r--src/unistd/_exit.h18
-rw-r--r--src/unistd/linux/pread.cpp5
-rw-r--r--src/unistd/linux/read.cpp5
-rw-r--r--test/IntegrationTest/test.h9
-rw-r--r--test/UnitTest/ErrnoSetterMatcher.h4
-rw-r--r--test/UnitTest/ExecuteFunction.h6
-rw-r--r--test/UnitTest/FPExceptMatcher.h6
-rw-r--r--test/UnitTest/FPMatcher.h35
-rw-r--r--test/UnitTest/FuchsiaTest.h9
-rw-r--r--test/UnitTest/LibcTest.cpp153
-rw-r--r--test/UnitTest/LibcTest.h22
-rw-r--r--test/UnitTest/MemoryMatcher.h6
-rw-r--r--test/UnitTest/PlatformDefs.h6
-rw-r--r--test/UnitTest/PrintfMatcher.cpp6
-rw-r--r--test/UnitTest/RoundingModeUtils.h6
-rw-r--r--test/UnitTest/StringUtils.h9
-rw-r--r--test/UnitTest/Test.h6
-rw-r--r--test/UnitTest/TestLogger.cpp21
-rw-r--r--test/include/stdbit_stub.h73
-rw-r--r--test/include/stdbit_test.c61
-rw-r--r--test/include/stdbit_test.cpp159
-rw-r--r--test/include/stdckdint_test.cpp32
-rw-r--r--test/include/sys/queue_test.cpp2
-rw-r--r--test/integration/src/__support/GPU/scan_reduce.cpp62
-rw-r--r--test/integration/src/pthread/pthread_create_test.cpp2
-rw-r--r--test/integration/src/pthread/pthread_join_test.cpp2
-rw-r--r--test/integration/src/spawn/test_binary_properties.h6
-rw-r--r--test/integration/src/stdio/gpu/printf.cpp88
-rw-r--r--test/integration/src/unistd/getcwd_test.cpp4
-rw-r--r--test/integration/startup/linux/tls_test.cpp4
-rw-r--r--test/src/__support/CPP/array_test.cpp66
-rw-r--r--test/src/__support/CPP/bit_test.cpp40
-rw-r--r--test/src/__support/CPP/limits_test.cpp12
-rw-r--r--test/src/__support/CPP/stringview_test.cpp108
-rw-r--r--test/src/__support/FPUtil/dyadic_float_test.cpp35
-rw-r--r--test/src/__support/FPUtil/fpbits_test.cpp489
-rw-r--r--test/src/__support/RPC/rpc_smoke_test.cpp10
-rw-r--r--test/src/__support/arg_list_test.cpp2
-rw-r--r--test/src/__support/blockstore_test.cpp8
-rw-r--r--test/src/__support/fixed_point/fx_bits_test.cpp397
-rw-r--r--test/src/__support/fixedvector_test.cpp16
-rw-r--r--test/src/__support/high_precision_decimal_test.cpp28
-rw-r--r--test/src/__support/integer_literals_test.cpp156
-rw-r--r--test/src/__support/integer_to_string_test.cpp44
-rw-r--r--test/src/__support/math_extras_test.cpp166
-rw-r--r--test/src/__support/memory_size_test.cpp7
-rw-r--r--test/src/__support/str_to_double_test.cpp2
-rw-r--r--test/src/__support/str_to_float_test.cpp2
-rw-r--r--test/src/__support/str_to_fp_test.h2
-rw-r--r--test/src/__support/str_to_integer_test.cpp240
-rw-r--r--test/src/__support/str_to_long_double_test.cpp56
-rw-r--r--test/src/__support/uint_test.cpp275
-rw-r--r--test/src/compiler/stack_chk_guard_test.cpp2
-rw-r--r--test/src/dirent/dirent_test.cpp8
-rw-r--r--test/src/errno/errno_test.cpp4
-rw-r--r--test/src/math/CeilTest.h2
-rw-r--r--test/src/math/CopySignTest.h2
-rw-r--r--test/src/math/FAbsTest.h7
-rw-r--r--test/src/math/FDimTest.h3
-rw-r--r--test/src/math/FMaxTest.h7
-rw-r--r--test/src/math/FMinTest.h7
-rw-r--r--test/src/math/FModTest.h2
-rw-r--r--test/src/math/FloorTest.h7
-rw-r--r--test/src/math/FmaTest.h1
-rw-r--r--test/src/math/FrexpTest.h2
-rw-r--r--test/src/math/HypotTest.h4
-rw-r--r--test/src/math/ILogbTest.h4
-rw-r--r--test/src/math/LdExpTest.h3
-rw-r--r--test/src/math/LogbTest.h2
-rw-r--r--test/src/math/ModfTest.h2
-rw-r--r--test/src/math/NextAfterTest.h3
-rw-r--r--test/src/math/RIntTest.h3
-rw-r--r--test/src/math/RandUtils.h5
-rw-r--r--test/src/math/RemQuoTest.h3
-rw-r--r--test/src/math/RoundEvenTest.h92
-rw-r--r--test/src/math/RoundTest.h7
-rw-r--r--test/src/math/RoundToIntegerTest.h5
-rw-r--r--test/src/math/SqrtTest.h2
-rw-r--r--test/src/math/TruncTest.h7
-rw-r--r--test/src/math/acosf_test.cpp4
-rw-r--r--test/src/math/acoshf_test.cpp4
-rw-r--r--test/src/math/asinf_test.cpp4
-rw-r--r--test/src/math/asinhf_test.cpp4
-rw-r--r--test/src/math/atan2f_test.cpp133
-rw-r--r--test/src/math/atanf_test.cpp18
-rw-r--r--test/src/math/atanhf_test.cpp6
-rw-r--r--test/src/math/cos_test.cpp2
-rw-r--r--test/src/math/cosf_test.cpp4
-rw-r--r--test/src/math/coshf_test.cpp6
-rw-r--r--test/src/math/differential_testing/ceilf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/cosf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/exp2f_diff.cpp16
-rw-r--r--test/src/math/differential_testing/expf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/expm1f_diff.cpp16
-rw-r--r--test/src/math/differential_testing/fabsf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/floorf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/hypot_diff.cpp16
-rw-r--r--test/src/math/differential_testing/hypotf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/log2f_diff.cpp16
-rw-r--r--test/src/math/differential_testing/logbf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/logf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/nearbyintf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/rintf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/roundf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/sinf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/sqrtf_diff.cpp16
-rw-r--r--test/src/math/differential_testing/truncf_diff.cpp16
-rw-r--r--test/src/math/erff_test.cpp2
-rw-r--r--test/src/math/exhaustive/atanf_test.cpp2
-rw-r--r--test/src/math/exhaustive/exp2m1f_test.cpp33
-rw-r--r--test/src/math/exhaustive/fmod_generic_impl_test.cpp43
-rw-r--r--test/src/math/exp10_test.cpp4
-rw-r--r--test/src/math/exp10f_test.cpp14
-rw-r--r--test/src/math/exp2_test.cpp4
-rw-r--r--test/src/math/exp2f_test.cpp14
-rw-r--r--test/src/math/exp2m1f_test.cpp66
-rw-r--r--test/src/math/exp_test.cpp4
-rw-r--r--test/src/math/expf_test.cpp14
-rw-r--r--test/src/math/explogxf_test.cpp10
-rw-r--r--test/src/math/expm1_test.cpp4
-rw-r--r--test/src/math/expm1f_test.cpp14
-rw-r--r--test/src/math/fdim_test.cpp2
-rw-r--r--test/src/math/fdimf_test.cpp2
-rw-r--r--test/src/math/fdiml_test.cpp2
-rw-r--r--test/src/math/ilogb_test.cpp2
-rw-r--r--test/src/math/ilogbf_test.cpp2
-rw-r--r--test/src/math/ilogbl_test.cpp2
-rw-r--r--test/src/math/in_float_range_test_helper.h6
-rw-r--r--test/src/math/inv_trigf_utils_test.cpp34
-rw-r--r--test/src/math/log10_test.cpp4
-rw-r--r--test/src/math/log10f_test.cpp2
-rw-r--r--test/src/math/log1p_test.cpp4
-rw-r--r--test/src/math/log1pf_test.cpp4
-rw-r--r--test/src/math/log2_test.cpp4
-rw-r--r--test/src/math/log2f_test.cpp6
-rw-r--r--test/src/math/log_test.cpp4
-rw-r--r--test/src/math/logf_test.cpp2
-rw-r--r--test/src/math/nextafterf128_test.cpp13
-rw-r--r--test/src/math/performance_testing/BinaryOpSingleOutputPerf.h (renamed from test/src/math/differential_testing/BinaryOpSingleOutputDiff.h)57
-rw-r--r--test/src/math/performance_testing/SingleInputSingleOutputPerf.h (renamed from test/src/math/differential_testing/SingleInputSingleOutputDiff.h)47
-rw-r--r--test/src/math/performance_testing/Timer.cpp (renamed from test/src/math/differential_testing/Timer.cpp)0
-rw-r--r--test/src/math/performance_testing/Timer.h (renamed from test/src/math/differential_testing/Timer.h)6
-rw-r--r--test/src/math/performance_testing/ceilf_perf.cpp (renamed from test/src/math/differential_testing/ceilf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/cosf_perf.cpp (renamed from test/src/math/differential_testing/cosf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/exp2f_perf.cpp (renamed from test/src/math/differential_testing/exp2f_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/expf_perf.cpp (renamed from test/src/math/differential_testing/expf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/expm1f_perf.cpp (renamed from test/src/math/differential_testing/expm1f_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/fabsf_perf.cpp (renamed from test/src/math/differential_testing/fabsf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/floorf_perf.cpp (renamed from test/src/math/differential_testing/floorf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/fmod_perf.cpp (renamed from test/src/math/differential_testing/fmod_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/fmodf128_perf.cpp (renamed from test/src/math/differential_testing/fmodf_diff.cpp)8
-rw-r--r--test/src/math/performance_testing/fmodf_perf.cpp (renamed from test/src/math/differential_testing/fmodf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/fmodl_perf.cpp (renamed from test/src/math/differential_testing/fmod_diff.cpp)8
-rw-r--r--test/src/math/performance_testing/hypot_perf.cpp (renamed from test/src/math/differential_testing/hypot_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/hypotf_perf.cpp (renamed from test/src/math/differential_testing/hypotf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/log10f_perf.cpp (renamed from test/src/math/differential_testing/log10f_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/log1pf_perf.cpp (renamed from test/src/math/differential_testing/log1pf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/log2f_perf.cpp (renamed from test/src/math/differential_testing/log2f_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/logbf_perf.cpp (renamed from test/src/math/differential_testing/logbf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/logf_perf.cpp (renamed from test/src/math/differential_testing/logf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/nearbyintf_perf.cpp (renamed from test/src/math/differential_testing/nearbyintf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/rintf_perf.cpp (renamed from test/src/math/differential_testing/rintf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/roundf_perf.cpp (renamed from test/src/math/differential_testing/roundf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/sinf_perf.cpp (renamed from test/src/math/differential_testing/sinf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/sqrtf_perf.cpp (renamed from test/src/math/differential_testing/sqrtf_perf.cpp)2
-rw-r--r--test/src/math/performance_testing/truncf_perf.cpp (renamed from test/src/math/differential_testing/truncf_perf.cpp)2
-rw-r--r--test/src/math/powf_test.cpp4
-rw-r--r--test/src/math/roundeven_test.cpp13
-rw-r--r--test/src/math/roundevenf_test.cpp13
-rw-r--r--test/src/math/roundevenl_test.cpp13
-rw-r--r--test/src/math/sin_test.cpp2
-rw-r--r--test/src/math/sincosf_test.cpp4
-rw-r--r--test/src/math/sinf_test.cpp4
-rw-r--r--test/src/math/sinhf_test.cpp6
-rw-r--r--test/src/math/smoke/CanonicalizeTest.h209
-rw-r--r--test/src/math/smoke/CeilTest.h7
-rw-r--r--test/src/math/smoke/CopySignTest.h7
-rw-r--r--test/src/math/smoke/FAbsTest.h7
-rw-r--r--test/src/math/smoke/FDimTest.h22
-rw-r--r--test/src/math/smoke/FMaxTest.h7
-rw-r--r--test/src/math/smoke/FMaximumMagNumTest.h101
-rw-r--r--test/src/math/smoke/FMaximumMagTest.h89
-rw-r--r--test/src/math/smoke/FMaximumNumTest.h100
-rw-r--r--test/src/math/smoke/FMaximumTest.h88
-rw-r--r--test/src/math/smoke/FMinTest.h5
-rw-r--r--test/src/math/smoke/FMinimumMagNumTest.h101
-rw-r--r--test/src/math/smoke/FMinimumMagTest.h89
-rw-r--r--test/src/math/smoke/FMinimumNumTest.h100
-rw-r--r--test/src/math/smoke/FMinimumTest.h88
-rw-r--r--test/src/math/smoke/FModTest.h2
-rw-r--r--test/src/math/smoke/FloorTest.h7
-rw-r--r--test/src/math/smoke/FmaTest.h1
-rw-r--r--test/src/math/smoke/FrexpTest.h58
-rw-r--r--test/src/math/smoke/FromfpTest.h528
-rw-r--r--test/src/math/smoke/FromfpxTest.h690
-rw-r--r--test/src/math/smoke/HypotTest.h4
-rw-r--r--test/src/math/smoke/ILogbTest.h116
-rw-r--r--test/src/math/smoke/LdExpTest.h5
-rw-r--r--test/src/math/smoke/LogbTest.h8
-rw-r--r--test/src/math/smoke/ModfTest.h8
-rw-r--r--test/src/math/smoke/NextAfterTest.h3
-rw-r--r--test/src/math/smoke/NextDownTest.h43
-rw-r--r--test/src/math/smoke/NextTowardTest.h3
-rw-r--r--test/src/math/smoke/NextUpTest.h43
-rw-r--r--test/src/math/smoke/RIntTest.h9
-rw-r--r--test/src/math/smoke/RemQuoTest.h3
-rw-r--r--test/src/math/smoke/RoundEvenTest.h72
-rw-r--r--test/src/math/smoke/RoundTest.h7
-rw-r--r--test/src/math/smoke/RoundToIntegerTest.h11
-rw-r--r--test/src/math/smoke/SqrtTest.h2
-rw-r--r--test/src/math/smoke/TruncTest.h7
-rw-r--r--test/src/math/smoke/UfromfpTest.h462
-rw-r--r--test/src/math/smoke/UfromfpxTest.h551
-rw-r--r--test/src/math/smoke/acosf_test.cpp4
-rw-r--r--test/src/math/smoke/acoshf_test.cpp4
-rw-r--r--test/src/math/smoke/asinf_test.cpp4
-rw-r--r--test/src/math/smoke/asinhf_test.cpp4
-rw-r--r--test/src/math/smoke/atan2f_test.cpp50
-rw-r--r--test/src/math/smoke/atanf_test.cpp4
-rw-r--r--test/src/math/smoke/atanhf_test.cpp6
-rw-r--r--test/src/math/smoke/canonicalize_test.cpp13
-rw-r--r--test/src/math/smoke/canonicalizef128_test.cpp13
-rw-r--r--test/src/math/smoke/canonicalizef_test.cpp13
-rw-r--r--test/src/math/smoke/canonicalizel_test.cpp19
-rw-r--r--test/src/math/smoke/ceilf128_test.cpp13
-rw-r--r--test/src/math/smoke/cosf_test.cpp4
-rw-r--r--test/src/math/smoke/coshf_test.cpp6
-rw-r--r--test/src/math/smoke/erff_test.cpp2
-rw-r--r--test/src/math/smoke/exp10_test.cpp2
-rw-r--r--test/src/math/smoke/exp10f_test.cpp6
-rw-r--r--test/src/math/smoke/exp2_test.cpp2
-rw-r--r--test/src/math/smoke/exp2f_test.cpp6
-rw-r--r--test/src/math/smoke/exp2m1f_test.cpp63
-rw-r--r--test/src/math/smoke/exp_test.cpp2
-rw-r--r--test/src/math/smoke/expf_test.cpp6
-rw-r--r--test/src/math/smoke/expm1_test.cpp2
-rw-r--r--test/src/math/smoke/expm1f_test.cpp6
-rw-r--r--test/src/math/smoke/fdim_test.cpp22
-rw-r--r--test/src/math/smoke/fdimf128_test.cpp13
-rw-r--r--test/src/math/smoke/fdimf_test.cpp24
-rw-r--r--test/src/math/smoke/fdiml_test.cpp24
-rw-r--r--test/src/math/smoke/floorf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_mag_num_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_mag_numf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_mag_numf_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_mag_numl_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_mag_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_magf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_magf_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_magl_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_num_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_numf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_numf_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_numl_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximum_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximumf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximumf_test.cpp13
-rw-r--r--test/src/math/smoke/fmaximuml_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_mag_num_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_mag_numf128_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_mag_numf_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_mag_numl_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_mag_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_magf128_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_magf_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_magl_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_num_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_numf128_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_numf_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_numl_test.cpp13
-rw-r--r--test/src/math/smoke/fminimum_test.cpp13
-rw-r--r--test/src/math/smoke/fminimumf128_test.cpp13
-rw-r--r--test/src/math/smoke/fminimumf_test.cpp13
-rw-r--r--test/src/math/smoke/fminimuml_test.cpp13
-rw-r--r--test/src/math/smoke/fmodf128_test.cpp13
-rw-r--r--test/src/math/smoke/fmodl_test.cpp13
-rw-r--r--test/src/math/smoke/frexp_test.cpp2
-rw-r--r--test/src/math/smoke/frexpf128_test.cpp13
-rw-r--r--test/src/math/smoke/frexpf_test.cpp2
-rw-r--r--test/src/math/smoke/frexpl_test.cpp2
-rw-r--r--test/src/math/smoke/fromfp_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpf128_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpf_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpl_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpx_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpxf128_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpxf_test.cpp13
-rw-r--r--test/src/math/smoke/fromfpxl_test.cpp13
-rw-r--r--test/src/math/smoke/ilogb_test.cpp25
-rw-r--r--test/src/math/smoke/ilogbf128_test.cpp13
-rw-r--r--test/src/math/smoke/ilogbf_test.cpp25
-rw-r--r--test/src/math/smoke/ilogbl_test.cpp25
-rw-r--r--test/src/math/smoke/ldexp_test.cpp2
-rw-r--r--test/src/math/smoke/ldexpf128_test.cpp13
-rw-r--r--test/src/math/smoke/ldexpf_test.cpp2
-rw-r--r--test/src/math/smoke/ldexpl_test.cpp2
-rw-r--r--test/src/math/smoke/llogb_test.cpp13
-rw-r--r--test/src/math/smoke/llogbf128_test.cpp13
-rw-r--r--test/src/math/smoke/llogbf_test.cpp13
-rw-r--r--test/src/math/smoke/llogbl_test.cpp13
-rw-r--r--test/src/math/smoke/llrintf128_test.cpp14
-rw-r--r--test/src/math/smoke/llroundf128_test.cpp13
-rw-r--r--test/src/math/smoke/log10_test.cpp2
-rw-r--r--test/src/math/smoke/log10f_test.cpp2
-rw-r--r--test/src/math/smoke/log1p_test.cpp2
-rw-r--r--test/src/math/smoke/log1pf_test.cpp2
-rw-r--r--test/src/math/smoke/log2_test.cpp2
-rw-r--r--test/src/math/smoke/log2f_test.cpp2
-rw-r--r--test/src/math/smoke/log_test.cpp2
-rw-r--r--test/src/math/smoke/logbf128_test.cpp13
-rw-r--r--test/src/math/smoke/logf_test.cpp2
-rw-r--r--test/src/math/smoke/lrintf128_test.cpp14
-rw-r--r--test/src/math/smoke/lroundf128_test.cpp13
-rw-r--r--test/src/math/smoke/modff128_test.cpp13
-rw-r--r--test/src/math/smoke/nanf128_test.cpp60
-rw-r--r--test/src/math/smoke/nanl_test.cpp8
-rw-r--r--test/src/math/smoke/nextafterf128_test.cpp13
-rw-r--r--test/src/math/smoke/nextdown_test.cpp13
-rw-r--r--test/src/math/smoke/nextdownf128_test.cpp13
-rw-r--r--test/src/math/smoke/nextdownf_test.cpp13
-rw-r--r--test/src/math/smoke/nextdownl_test.cpp13
-rw-r--r--test/src/math/smoke/nextup_test.cpp13
-rw-r--r--test/src/math/smoke/nextupf128_test.cpp13
-rw-r--r--test/src/math/smoke/nextupf_test.cpp13
-rw-r--r--test/src/math/smoke/nextupl_test.cpp13
-rw-r--r--test/src/math/smoke/powf_test.cpp2
-rw-r--r--test/src/math/smoke/rintf128_test.cpp13
-rw-r--r--test/src/math/smoke/roundeven_test.cpp12
-rw-r--r--test/src/math/smoke/roundevenf128_test.cpp12
-rw-r--r--test/src/math/smoke/roundevenf_test.cpp12
-rw-r--r--test/src/math/smoke/roundevenl_test.cpp12
-rw-r--r--test/src/math/smoke/roundf128_test.cpp13
-rw-r--r--test/src/math/smoke/sincosf_test.cpp4
-rw-r--r--test/src/math/smoke/sinf_test.cpp4
-rw-r--r--test/src/math/smoke/sinhf_test.cpp6
-rw-r--r--test/src/math/smoke/tanf_test.cpp4
-rw-r--r--test/src/math/smoke/tanhf_test.cpp4
-rw-r--r--test/src/math/smoke/truncf128_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfp_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpf128_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpf_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpl_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpx_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpxf128_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpxf_test.cpp13
-rw-r--r--test/src/math/smoke/ufromfpxl_test.cpp13
-rw-r--r--test/src/math/tan_test.cpp2
-rw-r--r--test/src/math/tanf_test.cpp4
-rw-r--r--test/src/math/tanhf_test.cpp4
-rw-r--r--test/src/sched/affinity_test.cpp8
-rw-r--r--test/src/sched/cpu_count_test.cpp2
-rw-r--r--test/src/sched/get_priority_test.cpp2
-rw-r--r--test/src/sched/param_and_scheduler_test.cpp45
-rw-r--r--test/src/sched/sched_rr_get_interval_test.cpp8
-rw-r--r--test/src/sched/yield_test.cpp2
-rw-r--r--test/src/search/insque_test.cpp186
-rw-r--r--test/src/signal/sigaltstack_test.cpp2
-rw-r--r--test/src/signal/signal_test.cpp2
-rw-r--r--test/src/signal/sigprocmask_test.cpp2
-rw-r--r--test/src/stdbit/stdc_bit_ceil_uc_test.cpp34
-rw-r--r--test/src/stdbit/stdc_bit_ceil_ui_test.cpp30
-rw-r--r--test/src/stdbit/stdc_bit_ceil_ul_test.cpp30
-rw-r--r--test/src/stdbit/stdc_bit_ceil_ull_test.cpp31
-rw-r--r--test/src/stdbit/stdc_bit_ceil_us_test.cpp34
-rw-r--r--test/src/stdbit/stdc_bit_floor_uc_test.cpp22
-rw-r--r--test/src/stdbit/stdc_bit_floor_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_floor_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_floor_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_floor_us_test.cpp22
-rw-r--r--test/src/stdbit/stdc_bit_width_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_width_ui_test.cpp20
-rw-r--r--test/src/stdbit/stdc_bit_width_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_width_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_bit_width_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_ones_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_ones_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_ones_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_ones_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_ones_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_zeros_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_zeros_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_zeros_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_zeros_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_count_zeros_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_one_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_one_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_one_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_one_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_one_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_zero_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_zero_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_zero_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_zero_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_leading_zero_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_trailing_one_uc_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_one_ui_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_one_ul_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_one_ull_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_one_us_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_zero_uc_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_zero_ui_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_zero_ul_test.cpp20
-rw-r--r--test/src/stdbit/stdc_first_trailing_zero_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_first_trailing_zero_us_test.cpp20
-rw-r--r--test/src/stdbit/stdc_has_single_bit_uc_test.cpp20
-rw-r--r--test/src/stdbit/stdc_has_single_bit_ui_test.cpp20
-rw-r--r--test/src/stdbit/stdc_has_single_bit_ul_test.cpp20
-rw-r--r--test/src/stdbit/stdc_has_single_bit_ull_test.cpp20
-rw-r--r--test/src/stdbit/stdc_has_single_bit_us_test.cpp20
-rw-r--r--test/src/stdbit/stdc_leading_ones_uc_test.cpp22
-rw-r--r--test/src/stdbit/stdc_leading_ones_ui_test.cpp22
-rw-r--r--test/src/stdbit/stdc_leading_ones_ul_test.cpp22
-rw-r--r--test/src/stdbit/stdc_leading_ones_ull_test.cpp22
-rw-r--r--test/src/stdbit/stdc_leading_ones_us_test.cpp22
-rw-r--r--test/src/stdbit/stdc_leading_zeros_uc_test.cpp4
-rw-r--r--test/src/stdbit/stdc_leading_zeros_ul_test.cpp4
-rw-r--r--test/src/stdbit/stdc_leading_zeros_ull_test.cpp4
-rw-r--r--test/src/stdbit/stdc_leading_zeros_us_test.cpp4
-rw-r--r--test/src/stdbit/stdc_trailing_ones_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_ones_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_ones_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_ones_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_ones_us_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_zeros_uc_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_zeros_ui_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_zeros_ul_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_zeros_ull_test.cpp21
-rw-r--r--test/src/stdbit/stdc_trailing_zeros_us_test.cpp21
-rw-r--r--test/src/stdfix/AbsTest.h37
-rw-r--r--test/src/stdfix/ExpTest.h77
-rw-r--r--test/src/stdfix/ISqrtTest.h63
-rw-r--r--test/src/stdfix/RoundTest.h65
-rw-r--r--test/src/stdfix/SqrtTest.h66
-rw-r--r--test/src/stdfix/abshk_test.cpp13
-rw-r--r--test/src/stdfix/abshr_test.cpp13
-rw-r--r--test/src/stdfix/absk_test.cpp13
-rw-r--r--test/src/stdfix/abslk_test.cpp13
-rw-r--r--test/src/stdfix/abslr_test.cpp13
-rw-r--r--test/src/stdfix/absr_test.cpp13
-rw-r--r--test/src/stdfix/exphk_test.cpp13
-rw-r--r--test/src/stdfix/expk_test.cpp13
-rw-r--r--test/src/stdfix/roundhk_test.cpp13
-rw-r--r--test/src/stdfix/roundhr_test.cpp13
-rw-r--r--test/src/stdfix/roundk_test.cpp13
-rw-r--r--test/src/stdfix/roundlk_test.cpp13
-rw-r--r--test/src/stdfix/roundlr_test.cpp13
-rw-r--r--test/src/stdfix/roundr_test.cpp13
-rw-r--r--test/src/stdfix/rounduhk_test.cpp13
-rw-r--r--test/src/stdfix/rounduhr_test.cpp13
-rw-r--r--test/src/stdfix/rounduk_test.cpp13
-rw-r--r--test/src/stdfix/roundulk_test.cpp13
-rw-r--r--test/src/stdfix/roundulr_test.cpp13
-rw-r--r--test/src/stdfix/roundur_test.cpp13
-rw-r--r--test/src/stdfix/sqrtuhk_test.cpp13
-rw-r--r--test/src/stdfix/sqrtuhr_test.cpp13
-rw-r--r--test/src/stdfix/sqrtuk_test.cpp13
-rw-r--r--test/src/stdfix/sqrtulr_test.cpp13
-rw-r--r--test/src/stdfix/sqrtur_test.cpp13
-rw-r--r--test/src/stdfix/uhksqrtus_test.cpp20
-rw-r--r--test/src/stdfix/uksqrtui_test.cpp20
-rw-r--r--test/src/stdio/fgetc_test.cpp2
-rw-r--r--test/src/stdio/fgetc_unlocked_test.cpp2
-rw-r--r--test/src/stdio/fgets_test.cpp2
-rw-r--r--test/src/stdio/fileop_test.cpp24
-rw-r--r--test/src/stdio/fopencookie_test.cpp8
-rw-r--r--test/src/stdio/ftell_test.cpp9
-rw-r--r--test/src/stdio/printf_core/converter_test.cpp14
-rw-r--r--test/src/stdio/printf_core/parser_test.cpp36
-rw-r--r--test/src/stdio/remove_test.cpp13
-rw-r--r--test/src/stdio/rename_test.cpp51
-rw-r--r--test/src/stdio/setvbuf_test.cpp2
-rw-r--r--test/src/stdio/sprintf_test.cpp547
-rw-r--r--test/src/stdio/sscanf_test.cpp2
-rw-r--r--test/src/stdio/unlocked_fileop_test.cpp4
-rw-r--r--test/src/stdlib/StrfromTest.h500
-rw-r--r--test/src/stdlib/StrtolTest.h124
-rw-r--r--test/src/stdlib/atof_test.cpp4
-rw-r--r--test/src/stdlib/strfromd_test.cpp13
-rw-r--r--test/src/stdlib/strfromf_test.cpp13
-rw-r--r--test/src/stdlib/strfroml_test.cpp13
-rw-r--r--test/src/stdlib/strtod_test.cpp2
-rw-r--r--test/src/stdlib/strtof_test.cpp2
-rw-r--r--test/src/stdlib/strtoint32_test.cpp4
-rw-r--r--test/src/stdlib/strtoint64_test.cpp4
-rw-r--r--test/src/stdlib/strtold_test.cpp12
-rw-r--r--test/src/string/memory_utils/op_tests.cpp15
-rw-r--r--test/src/string/memset_explicit_test.cpp31
-rw-r--r--test/src/string/strdup_test.cpp6
-rw-r--r--test/src/sys/epoll/linux/epoll_pwait2_test.cpp20
-rw-r--r--test/src/sys/epoll/linux/epoll_pwait_test.cpp20
-rw-r--r--test/src/sys/epoll/linux/epoll_wait_test.cpp20
-rw-r--r--test/src/sys/mman/linux/madvise_test.cpp6
-rw-r--r--test/src/sys/mman/linux/mincore_test.cpp25
-rw-r--r--test/src/sys/mman/linux/mlock_test.cpp203
-rw-r--r--test/src/sys/mman/linux/mmap_test.cpp6
-rw-r--r--test/src/sys/mman/linux/mprotect_test.cpp4
-rw-r--r--test/src/sys/mman/linux/msync_test.cpp69
-rw-r--r--test/src/sys/mman/linux/posix_madvise_test.cpp6
-rw-r--r--test/src/sys/mman/linux/shm_test.cpp77
-rw-r--r--test/src/sys/prctl/linux/prctl_test.cpp2
-rw-r--r--test/src/sys/random/linux/getrandom_test.cpp4
-rw-r--r--test/src/sys/resource/getrlimit_setrlimit_test.cpp6
-rw-r--r--test/src/sys/select/select_ui_test.cpp2
-rw-r--r--test/src/sys/sendfile/sendfile_test.cpp2
-rw-r--r--test/src/sys/socket/linux/bind_test.cpp1
-rw-r--r--test/src/sys/stat/chmod_test.cpp8
-rw-r--r--test/src/sys/stat/fchmod_test.cpp8
-rw-r--r--test/src/sys/stat/fchmodat_test.cpp8
-rw-r--r--test/src/sys/stat/fstat_test.cpp6
-rw-r--r--test/src/sys/stat/lstat_test.cpp6
-rw-r--r--test/src/sys/stat/mkdirat_test.cpp3
-rw-r--r--test/src/sys/stat/stat_test.cpp6
-rw-r--r--test/src/sys/statvfs/linux/fstatvfs_test.cpp42
-rw-r--r--test/src/sys/statvfs/linux/statvfs_test.cpp47
-rw-r--r--test/src/termios/termios_test.cpp10
-rw-r--r--test/src/time/TmHelper.h6
-rw-r--r--test/src/time/asctime_r_test.cpp6
-rw-r--r--test/src/time/asctime_test.cpp12
-rw-r--r--test/src/time/gmtime_test.cpp2
-rw-r--r--test/src/time/nanosleep_test.cpp2
-rw-r--r--test/src/unistd/_exit_test.cpp15
-rw-r--r--test/src/unistd/access_test.cpp10
-rw-r--r--test/src/unistd/chdir_test.cpp15
-rw-r--r--test/src/unistd/dup2_test.cpp5
-rw-r--r--test/src/unistd/dup3_test.cpp5
-rw-r--r--test/src/unistd/dup_test.cpp5
-rw-r--r--test/src/unistd/fchdir_test.cpp15
-rw-r--r--test/src/unistd/ftruncate_test.cpp7
-rw-r--r--test/src/unistd/isatty_test.cpp14
-rw-r--r--test/src/unistd/link_test.cpp13
-rw-r--r--test/src/unistd/linkat_test.cpp17
-rw-r--r--test/src/unistd/lseek_test.cpp6
-rw-r--r--test/src/unistd/pread_pwrite_test.cpp3
-rw-r--r--test/src/unistd/read_write_test.cpp7
-rw-r--r--test/src/unistd/readlink_test.cpp8
-rw-r--r--test/src/unistd/readlinkat_test.cpp8
-rw-r--r--test/src/unistd/rmdir_test.cpp6
-rw-r--r--test/src/unistd/symlink_test.cpp11
-rw-r--r--test/src/unistd/symlinkat_test.cpp17
-rw-r--r--test/src/unistd/syscall_test.cpp2
-rw-r--r--test/src/unistd/truncate_test.cpp5
-rw-r--r--test/src/unistd/unlink_test.cpp6
-rw-r--r--test/src/unistd/unlinkat_test.cpp9
-rw-r--r--test/utils/FPUtil/x86_long_double_test.cpp2
1512 files changed, 33618 insertions, 8104 deletions
diff --git a/include/__llvm-libc-common.h b/include/__llvm-libc-common.h
index 6b883ee21a8c..3af0b08e9e86 100644
--- a/include/__llvm-libc-common.h
+++ b/include/__llvm-libc-common.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC___COMMON_H
-#define LLVM_LIBC___COMMON_H
+#ifndef LLVM_LIBC_COMMON_H
+#define LLVM_LIBC_COMMON_H
#ifdef __cplusplus
@@ -51,4 +51,4 @@
#endif // __cplusplus
-#endif // LLVM_LIBC___COMMON_H
+#endif // LLVM_LIBC_COMMON_H
diff --git a/include/llvm-libc-macros/containerof-macro.h b/include/llvm-libc-macros/containerof-macro.h
index ea91fa7097a4..592acd6e3aa9 100644
--- a/include/llvm-libc-macros/containerof-macro.h
+++ b/include/llvm-libc-macros/containerof-macro.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
-#define __LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
+#ifndef LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
+#define LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
-#include <llvm-libc-macros/offsetof-macro.h>
+#include "llvm-libc-macros/offsetof-macro.h"
#define __containerof(ptr, type, member) \
({ \
@@ -17,4 +17,4 @@
(type *)(void *)((const char *)__ptr - offsetof(type, member)); \
})
-#endif // __LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
+#endif // LLVM_LIBC_MACROS_CONTAINEROF_MACRO_H
diff --git a/include/llvm-libc-macros/fcntl-macros.h b/include/llvm-libc-macros/fcntl-macros.h
index 448dcc0a8135..4bd03a7e3e2b 100644
--- a/include/llvm-libc-macros/fcntl-macros.h
+++ b/include/llvm-libc-macros/fcntl-macros.h
@@ -1,8 +1,8 @@
-#ifndef __LLVM_LIBC_MACROS_FCNTL_MACROS_H
-#define __LLVM_LIBC_MACROS_FCNTL_MACROS_H
+#ifndef LLVM_LIBC_MACROS_FCNTL_MACROS_H
+#define LLVM_LIBC_MACROS_FCNTL_MACROS_H
#ifdef __linux__
#include "linux/fcntl-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_FCNTL_MACROS_H
+#endif // LLVM_LIBC_MACROS_FCNTL_MACROS_H
diff --git a/include/llvm-libc-macros/features-macros.h b/include/llvm-libc-macros/features-macros.h
index 2938b3ccb95b..5bc87a68fc0b 100644
--- a/include/llvm-libc-macros/features-macros.h
+++ b/include/llvm-libc-macros/features-macros.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_FEATURES_MACROS_H
-#define __LLVM_LIBC_MACROS_FEATURES_MACROS_H
+#ifndef LLVM_LIBC_MACROS_FEATURES_MACROS_H
+#define LLVM_LIBC_MACROS_FEATURES_MACROS_H
#define __LLVM_LIBC__ 1
-#endif // __LLVM_LIBC_MACROS_FEATURES_MACROS_H
+#endif // LLVM_LIBC_MACROS_FEATURES_MACROS_H
diff --git a/include/llvm-libc-macros/fenv-macros.h b/include/llvm-libc-macros/fenv-macros.h
index cc0ea344b170..72ac660cd98c 100644
--- a/include/llvm-libc-macros/fenv-macros.h
+++ b/include/llvm-libc-macros/fenv-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_FENV_MACROS_H
-#define __LLVM_LIBC_MACROS_FENV_MACROS_H
+#ifndef LLVM_LIBC_MACROS_FENV_MACROS_H
+#define LLVM_LIBC_MACROS_FENV_MACROS_H
#define FE_DIVBYZERO 1
#define FE_INEXACT 2
@@ -24,4 +24,4 @@
#define FE_DFL_ENV ((fenv_t *)-1)
-#endif // __LLVM_LIBC_MACROS_FENV_MACROS_H
+#endif // LLVM_LIBC_MACROS_FENV_MACROS_H
diff --git a/include/llvm-libc-macros/file-seek-macros.h b/include/llvm-libc-macros/file-seek-macros.h
index 04f397982f46..676cb7511407 100644
--- a/include/llvm-libc-macros/file-seek-macros.h
+++ b/include/llvm-libc-macros/file-seek-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
-#define __LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
+#ifndef LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
+#define LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
-#endif // __LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
+#endif // LLVM_LIBC_MACROS_FILE_SEEK_MACROS_H
diff --git a/include/llvm-libc-macros/float-macros.h b/include/llvm-libc-macros/float-macros.h
index 86ec49393930..4fe8590c5f70 100644
--- a/include/llvm-libc-macros/float-macros.h
+++ b/include/llvm-libc-macros/float-macros.h
@@ -6,13 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_FLOAT_MACROS_H
-#define __LLVM_LIBC_MACROS_FLOAT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_FLOAT_MACROS_H
+#define LLVM_LIBC_MACROS_FLOAT_MACROS_H
// Suppress `#include_next is a language extension` warnings.
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-include-next"
+#pragma clang diagnostic ignored "-Winclude-next-absolute-path"
#else // gcc
#pragma GCC system_header
#endif //__clang__
@@ -169,4 +170,4 @@
// TODO: Add FLT16 and FLT128 constants.
-#endif // __LLVM_LIBC_MACROS_FLOAT_MACROS_H
+#endif // LLVM_LIBC_MACROS_FLOAT_MACROS_H
diff --git a/include/llvm-libc-macros/generic-error-number-macros.h b/include/llvm-libc-macros/generic-error-number-macros.h
index 3805c95cbb2a..7ee0352669b8 100644
--- a/include/llvm-libc-macros/generic-error-number-macros.h
+++ b/include/llvm-libc-macros/generic-error-number-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
-#define __LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
+#ifndef LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
+#define LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
#define EPERM 1
#define ENOENT 2
@@ -45,4 +45,4 @@
#define ERANGE 34
#define EILSEQ 35
-#endif // __LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
+#endif // LLVM_LIBC_MACROS_GENERIC_ERROR_NUMBER_MACROS_H
diff --git a/include/llvm-libc-macros/gpu/time-macros.h b/include/llvm-libc-macros/gpu/time-macros.h
index baf2ea5f4132..c3dc812f90a3 100644
--- a/include/llvm-libc-macros/gpu/time-macros.h
+++ b/include/llvm-libc-macros/gpu/time-macros.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
-#define __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+#ifndef LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
#define CLOCKS_PER_SEC 1000000
-#endif // __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+#endif // LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
diff --git a/include/llvm-libc-macros/inttypes-macros.h b/include/llvm-libc-macros/inttypes-macros.h
new file mode 100644
index 000000000000..9b554670271e
--- /dev/null
+++ b/include/llvm-libc-macros/inttypes-macros.h
@@ -0,0 +1,420 @@
+//===-- Definition of macros from inttypes.h ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_MACROS_INTTYPES_MACROS_H
+#define LLVM_LIBC_MACROS_INTTYPES_MACROS_H
+
+// fprintf/scanf format macros.
+#define __STDC_VERSION_INTTYPES_H__ 202311L
+
+// clang provides these macros, so we don't need to define them.
+#ifndef __clang__
+#if __UINTPTR_MAX__ == __UINT64_MAX__
+#define __PRI64 "l"
+#define __PRIPTR "l"
+#elif __UINTPTR_MAX__ == __UINT32_MAX__
+#define __PRI64 "ll"
+#define __PRIPTR ""
+#else
+// CHERI achitecture for example, has 128-bit pointers that use special "P"
+// format.
+#error "Unsupported pointer format"
+#endif
+#define __INT8_FMTd__ "hhd"
+#define __INT16_FMTd__ "hd"
+#define __INT32_FMTd__ "d"
+#define __INT64_FMTd__ __PRI64 "d"
+#define __INT_LEAST8_FMTd__ "hhd"
+#define __INT_LEAST16_FMTd__ "hd"
+#define __INT_LEAST32_FMTd__ "d"
+#define __INT_LEAST64_FMTd__ __PRI64 "d"
+#define __INT_FAST8_FMTd__ "hhd"
+#define __INT_FAST16_FMTd__ "hd"
+#define __INT_FAST32_FMTd__ "d"
+#define __INT_FAST64_FMTd__ __PRI64 "d"
+#define __INTMAX_FMTd__ __PRI64 "d"
+#define __INTPTR_FMTd__ __PRIPTR "d"
+
+#define __INT8_FMTi__ "hhi"
+#define __INT16_FMTi__ "hi"
+#define __INT32_FMTi__ "i"
+#define __INT64_FMTi__ __PRI64 "i"
+#define __INT_LEAST8_FMTi__ "hhi"
+#define __INT_LEAST16_FMTi__ "hi"
+#define __INT_LEAST32_FMTi__ "i"
+#define __INT_LEAST64_FMTi__ __PRI64 "i"
+#define __INT_FAST8_FMTi__ "hhi"
+#define __INT_FAST16_FMTi__ "hi"
+#define __INT_FAST32_FMTi__ "i"
+#define __INT_FAST64_FMTi__ __PRI64 "i"
+#define __INTMAX_FMTi__ __PRI64 "i"
+#define __INTPTR_FMTi__ __PRIPTR "i"
+
+#define __UINT8_FMTo__ "hho"
+#define __UINT16_FMTo__ "ho"
+#define __UINT32_FMTo__ "o"
+#define __UINT64_FMTo__ __PRI64 "o"
+#define __UINT_LEAST8_FMTo__ "hho"
+#define __UINT_LEAST16_FMTo__ "ho"
+#define __UINT_LEAST32_FMTo__ "o"
+#define __UINT_LEAST64_FMTo__ __PRI64 "o"
+#define __UINT_FAST8_FMTo__ "hho"
+#define __UINT_FAST16_FMTo__ "ho"
+#define __UINT_FAST32_FMTo__ "o"
+#define __UINT_FAST64_FMTo__ __PRI64 "o"
+#define __UINTMAX_FMTo__ __PRI64 "o"
+#define __UINTPTR_FMTo__ __PRIPTR "o"
+
+#define __UINT8_FMTu__ "hhu"
+#define __UINT16_FMTu__ "hu"
+#define __UINT32_FMTu__ "u"
+#define __UINT64_FMTu__ __PRI64 "u"
+#define __UINT_LEAST8_FMTu__ "hhu"
+#define __UINT_LEAST16_FMTu__ "hu"
+#define __UINT_LEAST32_FMTu__ "u"
+#define __UINT_LEAST64_FMTu__ __PRI64 "u"
+#define __UINT_FAST8_FMTu__ "hhu"
+#define __UINT_FAST16_FMTu__ "hu"
+#define __UINT_FAST32_FMTu__ "u"
+#define __UINT_FAST64_FMTu__ __PRI64 "u"
+#define __UINTMAX_FMTu__ __PRI64 "u"
+#define __UINTPTR_FMTu__ __PRIPTR "u"
+
+#define __UINT8_FMTx__ "hhx"
+#define __UINT16_FMTx__ "hx"
+#define __UINT32_FMTx__ "x"
+#define __UINT64_FMTx__ __PRI64 "x"
+#define __UINT_LEAST8_FMTx__ "hhx"
+#define __UINT_LEAST16_FMTx__ "hx"
+#define __UINT_LEAST32_FMTx__ "x"
+#define __UINT_LEAST64_FMTx__ __PRI64 "x"
+#define __UINT_FAST8_FMTx__ "hhx"
+#define __UINT_FAST16_FMTx__ "hx"
+#define __UINT_FAST32_FMTx__ "x"
+#define __UINT_FAST64_FMTx__ __PRI64 "x"
+#define __UINTMAX_FMTx__ __PRI64 "x"
+#define __UINTPTR_FMTx__ __PRIPTR "x"
+
+#define __UINT8_FMTX__ "hhX"
+#define __UINT16_FMTX__ "hX"
+#define __UINT32_FMTX__ "X"
+#define __UINT64_FMTX__ __PRI64 "X"
+#define __UINT_LEAST8_FMTX__ "hhX"
+#define __UINT_LEAST16_FMTX__ "hX"
+#define __UINT_LEAST32_FMTX__ "X"
+#define __UINT_LEAST64_FMTX__ __PRI64 "X"
+#define __UINT_FAST8_FMTX__ "hhX"
+#define __UINT_FAST16_FMTX__ "hX"
+#define __UINT_FAST32_FMTX__ "X"
+#define __UINT_FAST64_FMTX__ __PRI64 "X"
+#define __UINTMAX_FMTX__ __PRI64 "X"
+#define __UINTPTR_FMTX__ __PRIPTR "X"
+#endif
+
+// only recent clang provides these macros, so we need to check if they are
+// available.
+#ifndef __UINT8_FMTb__
+#define __UINT8_FMTb__ "hhb"
+#endif
+#ifndef __UINT16_FMTb__
+#define __UINT16_FMTb__ "hb"
+#endif
+#ifndef __UINT32_FMTb__
+#define __UINT32_FMTb__ "b"
+#endif
+#ifndef __UINT64_FMTb__
+#define __UINT64_FMTb__ __PRI64 "b"
+#endif
+#ifndef __UINT_LEAST8_FMTb__
+#define __UINT_LEAST8_FMTb__ "hhb"
+#endif
+#ifndef __UINT_LEAST16_FMTb__
+#define __UINT_LEAST16_FMTb__ "hb"
+#endif
+#ifndef __UINT_LEAST32_FMTb__
+#define __UINT_LEAST32_FMTb__ "b"
+#endif
+#ifndef __UINT_LEAST64_FMTb__
+#define __UINT_LEAST64_FMTb__ __PRI64 "b"
+#endif
+#ifndef __UINT_FAST8_FMTb__
+#define __UINT_FAST8_FMTb__ "hhb"
+#endif
+#ifndef __UINT_FAST16_FMTb__
+#define __UINT_FAST16_FMTb__ "hb"
+#endif
+#ifndef __UINT_FAST32_FMTb__
+#define __UINT_FAST32_FMTb__ "b"
+#endif
+#ifndef __UINT_FAST64_FMTb__
+#define __UINT_FAST64_FMTb__ __PRI64 "b"
+#endif
+#ifndef __UINTMAX_FMTb__
+#define __UINTMAX_FMTb__ __PRI64 "b"
+#endif
+#ifndef __UINTPTR_FMTb__
+#define __UINTPTR_FMTb__ __PRIPTR "b"
+#endif
+
+#ifndef __UINT8_FMTB__
+#define __UINT8_FMTB__ "hhB"
+#endif
+#ifndef __UINT16_FMTB__
+#define __UINT16_FMTB__ "hB"
+#endif
+#ifndef __UINT32_FMTB__
+#define __UINT32_FMTB__ "B"
+#endif
+#ifndef __UINT64_FMTB__
+#define __UINT64_FMTB__ __PRI64 "B"
+#endif
+#ifndef __UINT_LEAST8_FMTB__
+#define __UINT_LEAST8_FMTB__ "hhB"
+#endif
+#ifndef __UINT_LEAST16_FMTB__
+#define __UINT_LEAST16_FMTB__ "hB"
+#endif
+#ifndef __UINT_LEAST32_FMTB__
+#define __UINT_LEAST32_FMTB__ "B"
+#endif
+#ifndef __UINT_LEAST64_FMTB__
+#define __UINT_LEAST64_FMTB__ __PRI64 "B"
+#endif
+#ifndef __UINT_FAST8_FMTB__
+#define __UINT_FAST8_FMTB__ "hhB"
+#endif
+#ifndef __UINT_FAST16_FMTB__
+#define __UINT_FAST16_FMTB__ "hB"
+#endif
+#ifndef __UINT_FAST32_FMTB__
+#define __UINT_FAST32_FMTB__ "B"
+#endif
+#ifndef __UINT_FAST64_FMTB__
+#define __UINT_FAST64_FMTB__ __PRI64 "B"
+#endif
+#ifndef __UINTMAX_FMTB__
+#define __UINTMAX_FMTB__ __PRI64 "B"
+#endif
+#ifndef __UINTPTR_FMTB__
+#define __UINTPTR_FMTB__ __PRIPTR "B"
+#endif
+
+// The fprintf() macros for signed integers.
+#define PRId8 __INT8_FMTd__
+#define PRId16 __INT16_FMTd__
+#define PRId32 __INT32_FMTd__
+#define PRId64 __INT64_FMTd__
+#define PRIdLEAST8 __INT_LEAST8_FMTd__
+#define PRIdLEAST16 __INT_LEAST16_FMTd__
+#define PRIdLEAST32 __INT_LEAST32_FMTd__
+#define PRIdLEAST64 __INT_LEAST64_FMTd__
+#define PRIdFAST8 __INT_FAST8_FMTd__
+#define PRIdFAST16 __INT_FAST16_FMTd__
+#define PRIdFAST32 __INT_FAST32_FMTd__
+#define PRIdFAST64 __INT_FAST64_FMTd__
+#define PRIdMAX __INTMAX_FMTd__
+#define PRIdPTR __INTPTR_FMTd__
+
+#define PRIi8 __INT8_FMTi__
+#define PRIi16 __INT16_FMTi__
+#define PRIi32 __INT32_FMTi__
+#define PRIi64 __INT64_FMTi__
+#define PRIiLEAST8 __INT_LEAST8_FMTi__
+#define PRIiLEAST16 __INT_LEAST16_FMTi__
+#define PRIiLEAST32 __INT_LEAST32_FMTi__
+#define PRIiLEAST64 __INT_LEAST64_FMTi__
+#define PRIiFAST8 __INT_FAST8_FMTi__
+#define PRIiFAST16 __INT_FAST16_FMTi__
+#define PRIiFAST32 __INT_FAST32_FMTi__
+#define PRIiFAST64 __INT_FAST64_FMTi__
+#define PRIiMAX __INTMAX_FMTi__
+#define PRIiPTR __INTPTR_FMTi__
+
+// The fprintf() macros for unsigned integers.
+#define PRIo8 __UINT8_FMTo__
+#define PRIo16 __UINT16_FMTo__
+#define PRIo32 __UINT32_FMTo__
+#define PRIo64 __UINT64_FMTo__
+#define PRIoLEAST8 __UINT_LEAST8_FMTo__
+#define PRIoLEAST16 __UINT_LEAST16_FMTo__
+#define PRIoLEAST32 __UINT_LEAST32_FMTo__
+#define PRIoLEAST64 __UINT_LEAST64_FMTo__
+#define PRIoFAST8 __UINT_FAST8_FMTo__
+#define PRIoFAST16 __UINT_FAST16_FMTo__
+#define PRIoFAST32 __UINT_FAST32_FMTo__
+#define PRIoFAST64 __UINT_FAST64_FMTo__
+#define PRIoMAX __UINTMAX_FMTo__
+#define PRIoPTR __UINTPTR_FMTo__
+
+#define PRIu8 __UINT8_FMTu__
+#define PRIu16 __UINT16_FMTu__
+#define PRIu32 __UINT32_FMTu__
+#define PRIu64 __UINT64_FMTu__
+#define PRIuLEAST8 __UINT_LEAST8_FMTu__
+#define PRIuLEAST16 __UINT_LEAST16_FMTu__
+#define PRIuLEAST32 __UINT_LEAST32_FMTu__
+#define PRIuLEAST64 __UINT_LEAST64_FMTu__
+#define PRIuFAST8 __UINT_FAST8_FMTu__
+#define PRIuFAST16 __UINT_FAST16_FMTu__
+#define PRIuFAST32 __UINT_FAST32_FMTu__
+#define PRIuFAST64 __UINT_FAST64_FMTu__
+#define PRIuMAX __UINTMAX_FMTu__
+#define PRIuPTR __UINTPTR_FMTu__
+
+#define PRIx8 __UINT8_FMTx__
+#define PRIx16 __UINT16_FMTx__
+#define PRIx32 __UINT32_FMTx__
+#define PRIx64 __UINT64_FMTx__
+#define PRIxLEAST8 __UINT_LEAST8_FMTx__
+#define PRIxLEAST16 __UINT_LEAST16_FMTx__
+#define PRIxLEAST32 __UINT_LEAST32_FMTx__
+#define PRIxLEAST64 __UINT_LEAST64_FMTx__
+#define PRIxFAST8 __UINT_FAST8_FMTx__
+#define PRIxFAST16 __UINT_FAST16_FMTx__
+#define PRIxFAST32 __UINT_FAST32_FMTx__
+#define PRIxFAST64 __UINT_FAST64_FMTx__
+#define PRIxMAX __UINTMAX_FMTx__
+#define PRIxPTR __UINTPTR_FMTx__
+
+#define PRIX8 __UINT8_FMTX__
+#define PRIX16 __UINT16_FMTX__
+#define PRIX32 __UINT32_FMTX__
+#define PRIX64 __UINT64_FMTX__
+#define PRIXLEAST8 __UINT_LEAST8_FMTX__
+#define PRIXLEAST16 __UINT_LEAST16_FMTX__
+#define PRIXLEAST32 __UINT_LEAST32_FMTX__
+#define PRIXLEAST64 __UINT_LEAST64_FMTX__
+#define PRIXFAST8 __UINT_FAST8_FMTX__
+#define PRIXFAST16 __UINT_FAST16_FMTX__
+#define PRIXFAST32 __UINT_FAST32_FMTX__
+#define PRIXFAST64 __UINT_FAST64_FMTX__
+#define PRIXMAX __UINTMAX_FMTX__
+#define PRIXPTR __UINTPTR_FMTX__
+
+#define PRIb8 __UINT8_FMTb__
+#define PRIb16 __UINT16_FMTb__
+#define PRIb32 __UINT32_FMTb__
+#define PRIb64 __UINT64_FMTb__
+#define PRIbLEAST8 __UINT_LEAST8_FMTb__
+#define PRIbLEAST16 __UINT_LEAST16_FMTb__
+#define PRIbLEAST32 __UINT_LEAST32_FMTb__
+#define PRIbLEAST64 __UINT_LEAST64_FMTb__
+#define PRIbFAST8 __UINT_FAST8_FMTb__
+#define PRIbFAST16 __UINT_FAST16_FMTb__
+#define PRIbFAST32 __UINT_FAST32_FMTb__
+#define PRIbFAST64 __UINT_FAST64_FMTb__
+#define PRIbMAX __UINTMAX_FMTb__
+#define PRIbPTR __UINTPTR_FMTb__
+
+#define PRIB8 __UINT8_FMTB__
+#define PRIB16 __UINT16_FMTB__
+#define PRIB32 __UINT32_FMTB__
+#define PRIB64 __UINT64_FMTB__
+#define PRIBLEAST8 __UINT_LEAST8_FMTB__
+#define PRIBLEAST16 __UINT_LEAST16_FMTB__
+#define PRIBLEAST32 __UINT_LEAST32_FMTB__
+#define PRIBLEAST64 __UINT_LEAST64_FMTB__
+#define PRIBFAST8 __UINT_FAST8_FMTB__
+#define PRIBFAST16 __UINT_FAST16_FMTB__
+#define PRIBFAST32 __UINT_FAST32_FMTB__
+#define PRIBFAST64 __UINT_FAST64_FMTB__
+#define PRIBMAX __UINTMAX_FMTB__
+#define PRIBPTR __UINTPTR_FMTB__
+
+// The fscanf() macros for signed integers.
+#define SCNd8 __INT8_FMTd__
+#define SCNd16 __INT16_FMTd__
+#define SCNd32 __INT32_FMTd__
+#define SCNd64 __INT64_FMTd__
+#define SCNdLEAST8 __INT_LEAST8_FMTd__
+#define SCNdLEAST16 __INT_LEAST16_FMTd__
+#define SCNdLEAST32 __INT_LEAST32_FMTd__
+#define SCNdLEAST64 __INT_LEAST64_FMTd__
+#define SCNdFAST8 __INT_FAST8_FMTd__
+#define SCNdFAST16 __INT_FAST16_FMTd__
+#define SCNdFAST32 __INT_FAST32_FMTd__
+#define SCNdFAST64 __INT_FAST64_FMTd__
+#define SCNdMAX __INTMAX_FMTd__
+#define SCNdPTR __INTPTR_FMTd__
+
+#define SCNi8 __INT8_FMTi__
+#define SCNi16 __INT16_FMTi__
+#define SCNi32 __INT32_FMTi__
+#define SCNi64 __INT64_FMTi__
+#define SCNiLEAST8 __INT_LEAST8_FMTi__
+#define SCNiLEAST16 __INT_LEAST16_FMTi__
+#define SCNiLEAST32 __INT_LEAST32_FMTi__
+#define SCNiLEAST64 __INT_LEAST64_FMTi__
+#define SCNiFAST8 __INT_FAST8_FMTi__
+#define SCNiFAST16 __INT_FAST16_FMTi__
+#define SCNiFAST32 __INT_FAST32_FMTi__
+#define SCNiFAST64 __INT_FAST64_FMTi__
+#define SCNiMAX __INTMAX_FMTi__
+#define SCNiPTR __INTPTR_FMTi__
+
+// The fscanf() macros for unsigned integers.
+#define SCNo8 __UINT8_FMTo__
+#define SCNo16 __UINT16_FMTo__
+#define SCNo32 __UINT32_FMTo__
+#define SCNo64 __UINT64_FMTo__
+#define SCNoLEAST8 __UINT_LEAST8_FMTo__
+#define SCNoLEAST16 __UINT_LEAST16_FMTo__
+#define SCNoLEAST32 __UINT_LEAST32_FMTo__
+#define SCNoLEAST64 __UINT_LEAST64_FMTo__
+#define SCNoFAST8 __UINT_FAST8_FMTo__
+#define SCNoFAST16 __UINT_FAST16_FMTo__
+#define SCNoFAST32 __UINT_FAST32_FMTo__
+#define SCNoFAST64 __UINT_FAST64_FMTo__
+#define SCNoMAX __UINTMAX_FMTo__
+#define SCNoPTR __UINTPTR_FMTo__
+
+#define SCNu8 __UINT8_FMTu__
+#define SCNu16 __UINT16_FMTu__
+#define SCNu32 __UINT32_FMTu__
+#define SCNu64 __UINT64_FMTu__
+#define SCNuLEAST8 __UINT_LEAST8_FMTu__
+#define SCNuLEAST16 __UINT_LEAST16_FMTu__
+#define SCNuLEAST32 __UINT_LEAST32_FMTu__
+#define SCNuLEAST64 __UINT_LEAST64_FMTu__
+#define SCNuFAST8 __UINT_FAST8_FMTu__
+#define SCNuFAST16 __UINT_FAST16_FMTu__
+#define SCNuFAST32 __UINT_FAST32_FMTu__
+#define SCNuFAST64 __UINT_FAST64_FMTu__
+#define SCNuMAX __UINTMAX_FMTu__
+#define SCNuPTR __UINTPTR_FMTu__
+
+#define SCNx8 __UINT8_FMTx__
+#define SCNx16 __UINT16_FMTx__
+#define SCNx32 __UINT32_FMTx__
+#define SCNx64 __UINT64_FMTx__
+#define SCNxLEAST8 __UINT_LEAST8_FMTx__
+#define SCNxLEAST16 __UINT_LEAST16_FMTx__
+#define SCNxLEAST32 __UINT_LEAST32_FMTx__
+#define SCNxLEAST64 __UINT_LEAST64_FMTx__
+#define SCNxFAST8 __UINT_FAST8_FMTx__
+#define SCNxFAST16 __UINT_FAST16_FMTx__
+#define SCNxFAST32 __UINT_FAST32_FMTx__
+#define SCNxFAST64 __UINT_FAST64_FMTx__
+#define SCNxMAX __UINTMAX_FMTx__
+#define SCNxPTR __UINTPTR_FMTx__
+
+#define SCNb8 __UINT8_FMTb__
+#define SCNb16 __UINT16_FMTb__
+#define SCNb32 __UINT32_FMTb__
+#define SCNb64 __UINT64_FMTb__
+#define SCNbLEAST8 __UINT_LEAST8_FMTb__
+#define SCNbLEAST16 __UINT_LEAST16_FMTb__
+#define SCNbLEAST32 __UINT_LEAST32_FMTb__
+#define SCNbLEAST64 __UINT_LEAST64_FMTb__
+#define SCNbFAST8 __UINT_FAST8_FMTb__
+#define SCNbFAST16 __UINT_FAST16_FMTb__
+#define SCNbFAST32 __UINT_FAST32_FMTb__
+#define SCNbFAST64 __UINT_FAST64_FMTb__
+#define SCNbMAX __UINTMAX_FMTb__
+#define SCNbPTR __UINTPTR_FMTb__
+
+#endif // LLVM_LIBC_MACROS_INTTYPES_MACROS_H
diff --git a/include/llvm-libc-macros/limits-macros.h b/include/llvm-libc-macros/limits-macros.h
index 3b4df58ae4a1..95f0f5f0baa5 100644
--- a/include/llvm-libc-macros/limits-macros.h
+++ b/include/llvm-libc-macros/limits-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LIMITS_MACROS_H
-#define __LLVM_LIBC_MACROS_LIMITS_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LIMITS_MACROS_H
+#define LLVM_LIBC_MACROS_LIMITS_MACROS_H
// Define all C23 macro constants of limits.h
@@ -225,4 +225,4 @@
#define ULLONG_MIN 0ULL
#endif // ULLONG_MIN
-#endif // __LLVM_LIBC_MACROS_LIMITS_MACROS_H
+#endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H
diff --git a/include/llvm-libc-macros/linux/fcntl-macros.h b/include/llvm-libc-macros/linux/fcntl-macros.h
index 495c5ec780ed..1d4e5bbbdc77 100644
--- a/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
// File creation flags
#define O_CLOEXEC 02000000
@@ -68,4 +68,4 @@
#define F_GETFL 3
#define F_SETFL 4
-#endif // __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sched-macros.h b/include/llvm-libc-macros/linux/sched-macros.h
index 0c574440ccbc..ace620049ca0 100644
--- a/include/llvm-libc-macros/linux/sched-macros.h
+++ b/include/llvm-libc-macros/linux/sched-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
// Definitions of SCHED_* macros must match was linux as at:
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/sched.h
@@ -26,4 +26,4 @@
#define CPU_COUNT_S(setsize, set) __sched_getcpucount(setsize, set)
#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t), set)
-#endif // __LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SCHED_MACROS_H
diff --git a/include/llvm-libc-macros/linux/signal-macros.h b/include/llvm-libc-macros/linux/signal-macros.h
index deb190ec3759..e379fc41efd0 100644
--- a/include/llvm-libc-macros/linux/signal-macros.h
+++ b/include/llvm-libc-macros/linux/signal-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SIGNUM_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SIGNUM_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SIGNAL_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SIGNAL_MACROS_H
#define SIGHUP 1
#define SIGINT 2
@@ -101,4 +101,4 @@
#define CLD_STOPPED 5 // child has stopped
#define CLD_CONTINUED 6 // stopped child has continued
-#endif // __LLVM_LIBC_MACROS_LINUX_SIGNUM_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SIGNAL_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-ioctl-macros.h b/include/llvm-libc-macros/linux/sys-ioctl-macros.h
index 8f13a0ef4ad3..5eb779aeeca5 100644
--- a/include/llvm-libc-macros/linux/sys-ioctl-macros.h
+++ b/include/llvm-libc-macros/linux/sys-ioctl-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
// TODO (michaelrj): Finish defining these macros.
// Just defining this macro for the moment since it's all that we need right
@@ -16,4 +16,4 @@
// think is worth digging into right now.
#define TIOCGETD 0x5424
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_IOCTL_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-random-macros.h b/include/llvm-libc-macros/linux/sys-random-macros.h
index 1337f8b606fc..9261e87bdbf6 100644
--- a/include/llvm-libc-macros/linux/sys-random-macros.h
+++ b/include/llvm-libc-macros/linux/sys-random-macros.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
// Getrandom flags
#define GRND_RANDOM 0x0001
#define GRND_NONBLOCK 0x0002
#define GRND_INSECURE 0x0004
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-resource-macros.h b/include/llvm-libc-macros/linux/sys-resource-macros.h
index dd265530ada2..c9d93c30c35a 100644
--- a/include/llvm-libc-macros/linux/sys-resource-macros.h
+++ b/include/llvm-libc-macros/linux/sys-resource-macros.h
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
+
#define RLIMIT_CPU 0
#define RLIMIT_FSIZE 1
#define RLIMIT_DATA 2
@@ -24,3 +27,5 @@
#define RLIMIT_RTTIME 15
#define RLIM_INFINITY (~0UL)
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-socket-macros.h b/include/llvm-libc-macros/linux/sys-socket-macros.h
index 7de410225b71..f335200a103b 100644
--- a/include/llvm-libc-macros/linux/sys-socket-macros.h
+++ b/include/llvm-libc-macros/linux/sys-socket-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
// IEEE Std 1003.1-2017 - basedefs/sys_socket.h.html
// Macro values come from the Linux syscall interface.
@@ -25,4 +25,4 @@
#define SOCK_SEQPACKET 5
#define SOCK_PACKET 10
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-stat-macros.h b/include/llvm-libc-macros/linux/sys-stat-macros.h
index 48606cfa08ce..3013121d0f3c 100644
--- a/include/llvm-libc-macros/linux/sys-stat-macros.h
+++ b/include/llvm-libc-macros/linux/sys-stat-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
// Definitions from linux/stat.h
#define S_IFMT 0170000
@@ -45,4 +45,4 @@
#define S_IWOTH 00002
#define S_IXOTH 00001
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-time-macros.h b/include/llvm-libc-macros/linux/sys-time-macros.h
index 06ae43f0e005..e97819594adc 100644
--- a/include/llvm-libc-macros/linux/sys-time-macros.h
+++ b/include/llvm-libc-macros/linux/sys-time-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
// Add two timevals and put the result in timeval_ptr_result. If the resulting
// usec value is greater than 999,999 then the microseconds are turned into full
@@ -50,4 +50,4 @@
? ((timeval_ptr_a)->tv_usec CMP(timeval_ptr_b)->tv_usec) \
: ((timeval_ptr_a)->tv_sec CMP(timeval_ptr_b)->tv_sec))
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
diff --git a/include/llvm-libc-macros/linux/sys-wait-macros.h b/include/llvm-libc-macros/linux/sys-wait-macros.h
index 3e6c6f53cc71..c101638fdae3 100644
--- a/include/llvm-libc-macros/linux/sys-wait-macros.h
+++ b/include/llvm-libc-macros/linux/sys-wait-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
// Wait flags
#define WNOHANG 1 // Do not block
@@ -41,4 +41,4 @@
#define P_PGID 2
#define P_PIDFD 3
-#endif // __LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
diff --git a/include/llvm-libc-macros/linux/termios-macros.h b/include/llvm-libc-macros/linux/termios-macros.h
index 17e380ebecff..668cfe27abaa 100644
--- a/include/llvm-libc-macros/linux/termios-macros.h
+++ b/include/llvm-libc-macros/linux/termios-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
// Below are generic definitions of symbolic bit-masks, modes etc. They serve
// most architectures including x86_64, aarch64 but have to be adjusted for few
@@ -164,4 +164,4 @@
#define TCIOFF 2 // Suspend output
#define TCION 3 // Restart output
-#endif // __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H
diff --git a/include/llvm-libc-macros/linux/time-macros.h b/include/llvm-libc-macros/linux/time-macros.h
index ace27cb2e9eb..407a1eb30eea 100644
--- a/include/llvm-libc-macros/linux/time-macros.h
+++ b/include/llvm-libc-macros/linux/time-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
// clock type macros
#define CLOCK_REALTIME 0
@@ -23,4 +23,4 @@
#define CLOCKS_PER_SEC 1000000
-#endif //__LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
diff --git a/include/llvm-libc-macros/linux/unistd-macros.h b/include/llvm-libc-macros/linux/unistd-macros.h
index cfdfb9a93ee9..c5109df435e6 100644
--- a/include/llvm-libc-macros/linux/unistd-macros.h
+++ b/include/llvm-libc-macros/linux/unistd-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
-#define __LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
+#ifndef LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
// Values for mode argument to the access(...) function.
#define F_OK 0
@@ -27,4 +27,4 @@
(long)(arg4), (long)(arg5), (long)(arg6))
#define syscall(...) __syscall_helper(__VA_ARGS__, 0, 1, 2, 3, 4, 5, 6)
-#endif // __LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
+#endif // LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
diff --git a/include/llvm-libc-macros/math-macros.h b/include/llvm-libc-macros/math-macros.h
index 136670e665e6..6046ea98cb8a 100644
--- a/include/llvm-libc-macros/math-macros.h
+++ b/include/llvm-libc-macros/math-macros.h
@@ -6,8 +6,27 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_MATH_MACROS_H
-#define __LLVM_LIBC_MACROS_MATH_MACROS_H
+#ifndef LLVM_LIBC_MACROS_MATH_MACROS_H
+#define LLVM_LIBC_MACROS_MATH_MACROS_H
+
+// TODO: Remove this. This is a temporary fix for a downstream problem.
+// This cannot be left permanently since it would require downstream users to
+// define this macro.
+#ifdef LIBC_FULL_BUILD
+
+#include "limits-macros.h"
+
+#define FP_NAN 0
+#define FP_INFINITE 1
+#define FP_ZERO 2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL 4
+
+#define FP_INT_UPWARD 0
+#define FP_INT_DOWNWARD 1
+#define FP_INT_TOWARDZERO 2
+#define FP_INT_TONEARESTFROMZERO 3
+#define FP_INT_TONEAREST 4
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
@@ -16,19 +35,59 @@
#define INFINITY __builtin_inf()
#define NAN __builtin_nanf("")
-#define FP_ILOGB0 (-__INT_MAX__ - 1)
-#define FP_ILOGBNAN __INT_MAX__
+#define FP_ILOGB0 (-INT_MAX - 1)
+#define FP_LLOGB0 (-LONG_MAX - 1)
-#define isfinite(x) __builtin_isfinite(x)
-#define isinf(x) __builtin_isinf(x)
-#define isnan(x) __builtin_isnan(x)
+#ifdef __FP_LOGBNAN_MIN
+#define FP_ILOGBNAN (-INT_MAX - 1)
+#define FP_LLOGBNAN (-LONG_MAX - 1)
+#else
+#define FP_ILOGBNAN INT_MAX
+#define FP_LLOGBNAN LONG_MAX
+#endif
#ifdef __FAST_MATH__
#define math_errhandling 0
-#elif defined __NO_MATH_ERRNO__
+#elif defined(__NO_MATH_ERRNO__)
#define math_errhandling (MATH_ERREXCEPT)
+#elif defined(__NVPTX__) || defined(__AMDGPU__)
+#define math_errhandling (MATH_ERRNO)
#else
#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
#endif
-#endif // __LLVM_LIBC_MACROS_MATH_MACROS_H
+// These must be type-generic functions. The C standard specifies them as
+// being macros rather than functions, in fact. However, in C++ it's important
+// that there be function declarations that don't interfere with other uses of
+// the identifier, even in places with parentheses where a function-like macro
+// will be expanded (such as a function declaration in a C++ namespace).
+
+#ifdef __cplusplus
+
+template <typename T> inline constexpr bool isfinite(T x) {
+ return __builtin_isfinite(x);
+}
+
+template <typename T> inline constexpr bool isinf(T x) {
+ return __builtin_isinf(x);
+}
+
+template <typename T> inline constexpr bool isnan(T x) {
+ return __builtin_isnan(x);
+}
+
+#else
+
+#define isfinite(x) __builtin_isfinite(x)
+#define isinf(x) __builtin_isinf(x)
+#define isnan(x) __builtin_isnan(x)
+
+#endif
+
+#else // LIBC_FULL_BUILD
+
+#include <math.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_MACROS_MATH_MACROS_H
diff --git a/include/llvm-libc-macros/null-macro.h b/include/llvm-libc-macros/null-macro.h
index b83fc05c614d..416d4e865fc5 100644
--- a/include/llvm-libc-macros/null-macro.h
+++ b/include/llvm-libc-macros/null-macro.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_NULL_MACRO_H
-#define __LLVM_LIBC_MACROS_NULL_MACRO_H
+#ifndef LLVM_LIBC_MACROS_NULL_MACRO_H
+#define LLVM_LIBC_MACROS_NULL_MACRO_H
#define __need_NULL
#include <stddef.h>
-#endif // __LLVM_LIBC_MACROS_NULL_MACRO_H
+#endif // LLVM_LIBC_MACROS_NULL_MACRO_H
diff --git a/include/llvm-libc-macros/offsetof-macro.h b/include/llvm-libc-macros/offsetof-macro.h
index eeceb3db110b..208c06b29cb6 100644
--- a/include/llvm-libc-macros/offsetof-macro.h
+++ b/include/llvm-libc-macros/offsetof-macro.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
-#define __LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
+#ifndef LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
+#define LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
#define __need_offsetof
#include <stddef.h>
-#endif // __LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
+#endif // LLVM_LIBC_MACROS_OFFSETOF_MACRO_H
diff --git a/include/llvm-libc-macros/sched-macros.h b/include/llvm-libc-macros/sched-macros.h
index 760edd9feb72..0f643029816c 100644
--- a/include/llvm-libc-macros/sched-macros.h
+++ b/include/llvm-libc-macros/sched-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SCHED_MACROS_H
-#define __LLVM_LIBC_MACROS_SCHED_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SCHED_MACROS_H
+#define LLVM_LIBC_MACROS_SCHED_MACROS_H
#ifdef __linux__
#include "linux/sched-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SCHED_MACROS_H
+#endif // LLVM_LIBC_MACROS_SCHED_MACROS_H
diff --git a/include/llvm-libc-macros/signal-macros.h b/include/llvm-libc-macros/signal-macros.h
index 525032b3c5b1..7ab605baa54c 100644
--- a/include/llvm-libc-macros/signal-macros.h
+++ b/include/llvm-libc-macros/signal-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SIGNUM_MACROS_H
-#define __LLVM_LIBC_MACROS_SIGNUM_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SIGNAL_MACROS_H
+#define LLVM_LIBC_MACROS_SIGNAL_MACROS_H
#ifdef __linux__
#include "linux/signal-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SIGNUM_MACROS_H
+#endif // LLVM_LIBC_MACROS_SIGNAL_MACROS_H
diff --git a/include/llvm-libc-macros/stdbit-macros.h b/include/llvm-libc-macros/stdbit-macros.h
index da0fb1a578f1..c5b2f0977834 100644
--- a/include/llvm-libc-macros/stdbit-macros.h
+++ b/include/llvm-libc-macros/stdbit-macros.h
@@ -9,22 +9,209 @@
#ifndef __LLVM_LIBC_MACROS_STDBIT_MACROS_H
#define __LLVM_LIBC_MACROS_STDBIT_MACROS_H
+#define __STDC_VERSION_STDBIT_H__ 202311L
+#define __STDC_ENDIAN_LITTLE__ __ORDER_LITTLE_ENDIAN__
+#define __STDC_ENDIAN_BIG__ __ORDER_BIG_ENDIAN__
+#define __STDC_ENDIAN_NATIVE__ __BYTE_ORDER__
+
+// TODO(https://github.com/llvm/llvm-project/issues/80509): support _BitInt().
#ifdef __cplusplus
-inline unsigned char stdc_leading_zeros(unsigned char x) {
+inline unsigned stdc_leading_zeros(unsigned char x) {
return stdc_leading_zeros_uc(x);
}
-inline unsigned short stdc_leading_zeros(unsigned short x) {
+inline unsigned stdc_leading_zeros(unsigned short x) {
return stdc_leading_zeros_us(x);
}
inline unsigned stdc_leading_zeros(unsigned x) {
return stdc_leading_zeros_ui(x);
}
-inline unsigned long stdc_leading_zeros(unsigned long x) {
+inline unsigned stdc_leading_zeros(unsigned long x) {
return stdc_leading_zeros_ul(x);
}
-inline unsigned long long stdc_leading_zeros(unsigned long long x) {
+inline unsigned stdc_leading_zeros(unsigned long long x) {
return stdc_leading_zeros_ull(x);
}
+inline unsigned stdc_leading_ones(unsigned char x) {
+ return stdc_leading_ones_uc(x);
+}
+inline unsigned stdc_leading_ones(unsigned short x) {
+ return stdc_leading_ones_us(x);
+}
+inline unsigned stdc_leading_ones(unsigned x) {
+ return stdc_leading_ones_ui(x);
+}
+inline unsigned stdc_leading_ones(unsigned long x) {
+ return stdc_leading_ones_ul(x);
+}
+inline unsigned stdc_leading_ones(unsigned long long x) {
+ return stdc_leading_ones_ull(x);
+}
+inline unsigned stdc_trailing_zeros(unsigned char x) {
+ return stdc_trailing_zeros_uc(x);
+}
+inline unsigned stdc_trailing_zeros(unsigned short x) {
+ return stdc_trailing_zeros_us(x);
+}
+inline unsigned stdc_trailing_zeros(unsigned x) {
+ return stdc_trailing_zeros_ui(x);
+}
+inline unsigned stdc_trailing_zeros(unsigned long x) {
+ return stdc_trailing_zeros_ul(x);
+}
+inline unsigned stdc_trailing_zeros(unsigned long long x) {
+ return stdc_trailing_zeros_ull(x);
+}
+inline unsigned stdc_trailing_ones(unsigned char x) {
+ return stdc_trailing_ones_uc(x);
+}
+inline unsigned stdc_trailing_ones(unsigned short x) {
+ return stdc_trailing_ones_us(x);
+}
+inline unsigned stdc_trailing_ones(unsigned x) {
+ return stdc_trailing_ones_ui(x);
+}
+inline unsigned stdc_trailing_ones(unsigned long x) {
+ return stdc_trailing_ones_ul(x);
+}
+inline unsigned stdc_trailing_ones(unsigned long long x) {
+ return stdc_trailing_ones_ull(x);
+}
+inline unsigned stdc_first_leading_zero(unsigned char x) {
+ return stdc_first_leading_zero_uc(x);
+}
+inline unsigned stdc_first_leading_zero(unsigned short x) {
+ return stdc_first_leading_zero_us(x);
+}
+inline unsigned stdc_first_leading_zero(unsigned x) {
+ return stdc_first_leading_zero_ui(x);
+}
+inline unsigned stdc_first_leading_zero(unsigned long x) {
+ return stdc_first_leading_zero_ul(x);
+}
+inline unsigned stdc_first_leading_zero(unsigned long long x) {
+ return stdc_first_leading_zero_ull(x);
+}
+inline unsigned stdc_first_leading_one(unsigned char x) {
+ return stdc_first_leading_one_uc(x);
+}
+inline unsigned stdc_first_leading_one(unsigned short x) {
+ return stdc_first_leading_one_us(x);
+}
+inline unsigned stdc_first_leading_one(unsigned x) {
+ return stdc_first_leading_one_ui(x);
+}
+inline unsigned stdc_first_leading_one(unsigned long x) {
+ return stdc_first_leading_one_ul(x);
+}
+inline unsigned stdc_first_leading_one(unsigned long long x) {
+ return stdc_first_leading_one_ull(x);
+}
+inline unsigned stdc_first_trailing_zero(unsigned char x) {
+ return stdc_first_trailing_zero_uc(x);
+}
+inline unsigned stdc_first_trailing_zero(unsigned short x) {
+ return stdc_first_trailing_zero_us(x);
+}
+inline unsigned stdc_first_trailing_zero(unsigned x) {
+ return stdc_first_trailing_zero_ui(x);
+}
+inline unsigned stdc_first_trailing_zero(unsigned long x) {
+ return stdc_first_trailing_zero_ul(x);
+}
+inline unsigned stdc_first_trailing_zero(unsigned long long x) {
+ return stdc_first_trailing_zero_ull(x);
+}
+inline unsigned stdc_first_trailing_one(unsigned char x) {
+ return stdc_first_trailing_one_uc(x);
+}
+inline unsigned stdc_first_trailing_one(unsigned short x) {
+ return stdc_first_trailing_one_us(x);
+}
+inline unsigned stdc_first_trailing_one(unsigned x) {
+ return stdc_first_trailing_one_ui(x);
+}
+inline unsigned stdc_first_trailing_one(unsigned long x) {
+ return stdc_first_trailing_one_ul(x);
+}
+inline unsigned stdc_first_trailing_one(unsigned long long x) {
+ return stdc_first_trailing_one_ull(x);
+}
+inline unsigned stdc_count_zeros(unsigned char x) {
+ return stdc_count_zeros_uc(x);
+}
+inline unsigned stdc_count_zeros(unsigned short x) {
+ return stdc_count_zeros_us(x);
+}
+inline unsigned stdc_count_zeros(unsigned x) { return stdc_count_zeros_ui(x); }
+inline unsigned stdc_count_zeros(unsigned long x) {
+ return stdc_count_zeros_ul(x);
+}
+inline unsigned stdc_count_zeros(unsigned long long x) {
+ return stdc_count_zeros_ull(x);
+}
+inline unsigned stdc_count_ones(unsigned char x) {
+ return stdc_count_ones_uc(x);
+}
+inline unsigned stdc_count_ones(unsigned short x) {
+ return stdc_count_ones_us(x);
+}
+inline unsigned stdc_count_ones(unsigned x) { return stdc_count_ones_ui(x); }
+inline unsigned stdc_count_ones(unsigned long x) {
+ return stdc_count_ones_ul(x);
+}
+inline unsigned stdc_count_ones(unsigned long long x) {
+ return stdc_count_ones_ull(x);
+}
+inline bool stdc_has_single_bit(unsigned char x) {
+ return stdc_has_single_bit_uc(x);
+}
+inline bool stdc_has_single_bit(unsigned short x) {
+ return stdc_has_single_bit_us(x);
+}
+inline bool stdc_has_single_bit(unsigned x) {
+ return stdc_has_single_bit_ui(x);
+}
+inline bool stdc_has_single_bit(unsigned long x) {
+ return stdc_has_single_bit_ul(x);
+}
+inline bool stdc_has_single_bit(unsigned long long x) {
+ return stdc_has_single_bit_ull(x);
+}
+inline unsigned stdc_bit_width(unsigned char x) { return stdc_bit_width_uc(x); }
+inline unsigned stdc_bit_width(unsigned short x) {
+ return stdc_bit_width_us(x);
+}
+inline unsigned stdc_bit_width(unsigned x) { return stdc_bit_width_ui(x); }
+inline unsigned stdc_bit_width(unsigned long x) { return stdc_bit_width_ul(x); }
+inline unsigned stdc_bit_width(unsigned long long x) {
+ return stdc_bit_width_ull(x);
+}
+inline unsigned char stdc_bit_floor(unsigned char x) {
+ return stdc_bit_floor_uc(x);
+}
+inline unsigned short stdc_bit_floor(unsigned short x) {
+ return stdc_bit_floor_us(x);
+}
+inline unsigned stdc_bit_floor(unsigned x) { return stdc_bit_floor_ui(x); }
+inline unsigned long stdc_bit_floor(unsigned long x) {
+ return stdc_bit_floor_ul(x);
+}
+inline unsigned long long stdc_bit_floor(unsigned long long x) {
+ return stdc_bit_floor_ull(x);
+}
+inline unsigned char stdc_bit_ceil(unsigned char x) {
+ return stdc_bit_ceil_uc(x);
+}
+inline unsigned short stdc_bit_ceil(unsigned short x) {
+ return stdc_bit_ceil_us(x);
+}
+inline unsigned stdc_bit_ceil(unsigned x) { return stdc_bit_ceil_ui(x); }
+inline unsigned long stdc_bit_ceil(unsigned long x) {
+ return stdc_bit_ceil_ul(x);
+}
+inline unsigned long long stdc_bit_ceil(unsigned long long x) {
+ return stdc_bit_ceil_ull(x);
+}
#else
#define stdc_leading_zeros(x) \
_Generic((x), \
@@ -33,6 +220,97 @@ inline unsigned long long stdc_leading_zeros(unsigned long long x) {
unsigned: stdc_leading_zeros_ui, \
unsigned long: stdc_leading_zeros_ul, \
unsigned long long: stdc_leading_zeros_ull)(x)
+#define stdc_leading_ones(x) \
+ _Generic((x), \
+ unsigned char: stdc_leading_ones_uc, \
+ unsigned short: stdc_leading_ones_us, \
+ unsigned: stdc_leading_ones_ui, \
+ unsigned long: stdc_leading_ones_ul, \
+ unsigned long long: stdc_leading_ones_ull)(x)
+#define stdc_trailing_zeros(x) \
+ _Generic((x), \
+ unsigned char: stdc_trailing_zeros_uc, \
+ unsigned short: stdc_trailing_zeros_us, \
+ unsigned: stdc_trailing_zeros_ui, \
+ unsigned long: stdc_trailing_zeros_ul, \
+ unsigned long long: stdc_trailing_zeros_ull)(x)
+#define stdc_trailing_ones(x) \
+ _Generic((x), \
+ unsigned char: stdc_trailing_ones_uc, \
+ unsigned short: stdc_trailing_ones_us, \
+ unsigned: stdc_trailing_ones_ui, \
+ unsigned long: stdc_trailing_ones_ul, \
+ unsigned long long: stdc_trailing_ones_ull)(x)
+#define stdc_first_leading_zero(x) \
+ _Generic((x), \
+ unsigned char: stdc_first_leading_zero_uc, \
+ unsigned short: stdc_first_leading_zero_us, \
+ unsigned: stdc_first_leading_zero_ui, \
+ unsigned long: stdc_first_leading_zero_ul, \
+ unsigned long long: stdc_first_leading_zero_ull)(x)
+#define stdc_first_leading_one(x) \
+ _Generic((x), \
+ unsigned char: stdc_first_leading_one_uc, \
+ unsigned short: stdc_first_leading_one_us, \
+ unsigned: stdc_first_leading_one_ui, \
+ unsigned long: stdc_first_leading_one_ul, \
+ unsigned long long: stdc_first_leading_one_ull)(x)
+#define stdc_first_trailing_zero(x) \
+ _Generic((x), \
+ unsigned char: stdc_first_trailing_zero_uc, \
+ unsigned short: stdc_first_trailing_zero_us, \
+ unsigned: stdc_first_trailing_zero_ui, \
+ unsigned long: stdc_first_trailing_zero_ul, \
+ unsigned long long: stdc_first_trailing_zero_ull)(x)
+#define stdc_first_trailing_one(x) \
+ _Generic((x), \
+ unsigned char: stdc_first_trailing_one_uc, \
+ unsigned short: stdc_first_trailing_one_us, \
+ unsigned: stdc_first_trailing_one_ui, \
+ unsigned long: stdc_first_trailing_one_ul, \
+ unsigned long long: stdc_first_trailing_one_ull)(x)
+#define stdc_count_zeros(x) \
+ _Generic((x), \
+ unsigned char: stdc_count_zeros_uc, \
+ unsigned short: stdc_count_zeros_us, \
+ unsigned: stdc_count_zeros_ui, \
+ unsigned long: stdc_count_zeros_ul, \
+ unsigned long long: stdc_count_zeros_ull)(x)
+#define stdc_count_ones(x) \
+ _Generic((x), \
+ unsigned char: stdc_count_ones_uc, \
+ unsigned short: stdc_count_ones_us, \
+ unsigned: stdc_count_ones_ui, \
+ unsigned long: stdc_count_ones_ul, \
+ unsigned long long: stdc_count_ones_ull)(x)
+#define stdc_has_single_bit(x) \
+ _Generic((x), \
+ unsigned char: stdc_has_single_bit_uc, \
+ unsigned short: stdc_has_single_bit_us, \
+ unsigned: stdc_has_single_bit_ui, \
+ unsigned long: stdc_has_single_bit_ul, \
+ unsigned long long: stdc_has_single_bit_ull)(x)
+#define stdc_bit_width(x) \
+ _Generic((x), \
+ unsigned char: stdc_bit_width_uc, \
+ unsigned short: stdc_bit_width_us, \
+ unsigned: stdc_bit_width_ui, \
+ unsigned long: stdc_bit_width_ul, \
+ unsigned long long: stdc_bit_width_ull)(x)
+#define stdc_bit_floor(x) \
+ _Generic((x), \
+ unsigned char: stdc_bit_floor_uc, \
+ unsigned short: stdc_bit_floor_us, \
+ unsigned: stdc_bit_floor_ui, \
+ unsigned long: stdc_bit_floor_ul, \
+ unsigned long long: stdc_bit_floor_ull)(x)
+#define stdc_bit_ceil(x) \
+ _Generic((x), \
+ unsigned char: stdc_bit_ceil_uc, \
+ unsigned short: stdc_bit_ceil_us, \
+ unsigned: stdc_bit_ceil_ui, \
+ unsigned long: stdc_bit_ceil_ul, \
+ unsigned long long: stdc_bit_ceil_ull)(x)
#endif // __cplusplus
#endif // __LLVM_LIBC_MACROS_STDBIT_MACROS_H
diff --git a/include/llvm-libc-macros/stdckdint-macros.h b/include/llvm-libc-macros/stdckdint-macros.h
new file mode 100644
index 000000000000..694412290bbc
--- /dev/null
+++ b/include/llvm-libc-macros/stdckdint-macros.h
@@ -0,0 +1,25 @@
+//===-- Definition of macros for stdckdint.h ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
+#define LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
+
+// We need to use __builtin_*_overflow from GCC/Clang to implement the overflow
+// macros. Check __GNUC__ for availability of such builtins.
+#ifdef __GNUC__
+// clang/gcc overlay may provides similar macros, we need to avoid redefining
+// them.
+#ifndef __STDC_VERSION_STDCKDINT_H__
+#define __STDC_VERSION_STDCKDINT_H__ 202311L
+
+#define ckd_add(R, A, B) __builtin_add_overflow((A), (B), (R))
+#define ckd_sub(R, A, B) __builtin_sub_overflow((A), (B), (R))
+#define ckd_mul(R, A, B) __builtin_mul_overflow((A), (B), (R))
+#endif // __STDC_VERSION_STDCKDINT_H__
+#endif // __GNUC__
+#endif // LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
diff --git a/include/llvm-libc-macros/stdfix-macros.h b/include/llvm-libc-macros/stdfix-macros.h
new file mode 100644
index 000000000000..554ebe544a42
--- /dev/null
+++ b/include/llvm-libc-macros/stdfix-macros.h
@@ -0,0 +1,328 @@
+//===-- Definitions from stdfix.h -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_STDFIX_MACROS_H
+#define LLVM_LIBC_MACROS_STDFIX_MACROS_H
+
+#ifdef __FRACT_FBIT__
+// _Fract and _Accum types are available
+#define LIBC_COMPILER_HAS_FIXED_POINT
+#endif // __FRACT_FBIT__
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+
+#define fract _Fract
+#define accum _Accum
+#define sat _Sat
+
+// Default values: from ISO/IEC TR 18037:2008 standard - Annex A.3 - Typical
+// desktop processor.
+
+#ifdef __SFRACT_FBIT__
+#define SFRACT_FBIT __SFRACT_FBIT__
+#else
+#define SFRACT_FBIT 7
+#endif // SFRACT_FBIT
+
+#ifdef __SFRACT_MIN__
+#define SFRACT_MIN __SFRACT_MIN__
+#else
+#define SFRACT_MIN (-0.5HR - 0.5HR)
+#endif // SFRACT_MIN
+
+#ifdef __SFRACT_MAX__
+#define SFRACT_MAX __SFRACT_MAX__
+#else
+#define SFRACT_MAX 0x1.FCp-1HR
+#endif // SFRACT_MAX
+
+#ifdef __SFRACT_EPSILON__
+#define SFRACT_EPSILON __SFRACT_EPSILON__
+#else
+#define SFRACT_EPSILON 0x1.0p-7HR
+#endif // SFRACT_EPSILON
+
+#ifdef __USFRACT_FBIT__
+#define USFRACT_FBIT __USFRACT_FBIT__
+#else
+#define USFRACT_FBIT 8
+#endif // USFRACT_FBIT
+
+#define USFRACT_MIN 0.0UHR
+
+#ifdef __USFRACT_MAX__
+#define USFRACT_MAX __USFRACT_MAX__
+#else
+#define USFRACT_MAX 0x1.FEp-1UHR
+#endif // USFRACT_MAX
+
+#ifdef __USFRACT_EPSILON__
+#define USFRACT_EPSILON __USFRACT_EPSILON__
+#else
+#define USFRACT_EPSILON 0x1.0p-8UHR
+#endif // USFRACT_EPSILON
+
+#ifdef __FRACT_FBIT__
+#define FRACT_FBIT __FRACT_FBIT__
+#else
+#define FRACT_FBIT 15
+#endif // FRACT_FBIT
+
+#ifdef __FRACT_MIN__
+#define FRACT_MIN __FRACT_MIN__
+#else
+#define FRACT_MIN (-0.5R - 0.5R)
+#endif // FRACT_MIN
+
+#ifdef __FRACT_MAX__
+#define FRACT_MAX __FRACT_MAX__
+#else
+#define FRACT_MAX 0x1.FFFCp-1R
+#endif // FRACT_MAX
+
+#ifdef __FRACT_EPSILON__
+#define FRACT_EPSILON __FRACT_EPSILON__
+#else
+#define FRACT_EPSILON 0x1.0p-15R
+#endif // FRACT_EPSILON
+
+#ifdef __UFRACT_FBIT__
+#define UFRACT_FBIT __UFRACT_FBIT__
+#else
+#define UFRACT_FBIT 16
+#endif // UFRACT_FBIT
+
+#define UFRACT_MIN 0.0UR
+
+#ifdef __UFRACT_MAX__
+#define UFRACT_MAX __UFRACT_MAX__
+#else
+#define UFRACT_MAX 0x1.FFFEp-1UR
+#endif // UFRACT_MAX
+
+#ifdef __UFRACT_EPSILON__
+#define UFRACT_EPSILON __UFRACT_EPSILON__
+#else
+#define UFRACT_EPSILON 0x1.0p-16UR
+#endif // UFRACT_EPSILON
+
+#ifdef __LFRACT_FBIT__
+#define LFRACT_FBIT __LFRACT_FBIT__
+#else
+#define LFRACT_FBIT 31
+#endif // LFRACT_FBIT
+
+#ifdef __LFRACT_MIN__
+#define LFRACT_MIN __LFRACT_MIN__
+#else
+#define LFRACT_MIN (-0.5LR - 0.5LR)
+#endif // LFRACT_MIN
+
+#ifdef __LFRACT_MAX__
+#define LFRACT_MAX __LFRACT_MAX__
+#else
+#define LFRACT_MAX 0x1.FFFFFFFCp-1LR
+#endif // LFRACT_MAX
+
+#ifdef __LFRACT_EPSILON__
+#define LFRACT_EPSILON __LFRACT_EPSILON__
+#else
+#define LFRACT_EPSILON 0x1.0p-31LR
+#endif // LFRACT_EPSILON
+
+#ifdef __ULFRACT_FBIT__
+#define ULFRACT_FBIT __ULFRACT_FBIT__
+#else
+#define ULFRACT_FBIT 32
+#endif // ULFRACT_FBIT
+
+#define ULFRACT_MIN 0.0ULR
+
+#ifdef __ULFRACT_MAX__
+#define ULFRACT_MAX __ULFRACT_MAX__
+#else
+#define ULFRACT_MAX 0x1.FFFFFFFEp-1ULR
+#endif // ULFRACT_MAX
+
+#ifdef __ULFRACT_EPSILON__
+#define ULFRACT_EPSILON __ULFRACT_EPSILON__
+#else
+#define ULFRACT_EPSILON 0x1.0p-32ULR
+#endif // ULFRACT_EPSILON
+
+#ifdef __SACCUM_FBIT__
+#define SACCUM_FBIT __SACCUM_FBIT__
+#else
+#define SACCUM_FBIT 7
+#endif // SACCUM_FBIT
+
+#ifdef __SACCUM_IBIT__
+#define SACCUM_IBIT __SACCUM_IBIT__
+#else
+#define SACCUM_IBIT 8
+#endif // SACCUM_IBIT
+
+#ifdef __SACCUM_MIN__
+#define SACCUM_MIN __SACCUM_MIN__
+#else
+#define SACCUM_MIN (-0x1.0p+7HK - 0x1.0p+7HK)
+#endif // SACCUM_MIN
+
+#ifdef __SACCUM_MAX__
+#define SACCUM_MAX __SACCUM_MAX__
+#else
+#define SACCUM_MAX 0x1.FFFCp+7HK
+#endif // SACCUM_MAX
+
+#ifdef __SACCUM_EPSILON__
+#define SACCUM_EPSILON __SACCUM_EPSILON__
+#else
+#define SACCUM_EPSILON 0x1.0p-7HK
+#endif // SACCUM_EPSILON
+
+#ifdef __USACCUM_FBIT__
+#define USACCUM_FBIT __USACCUM_FBIT__
+#else
+#define USACCUM_FBIT 8
+#endif // USACCUM_FBIT
+
+#ifdef __USACCUM_IBIT__
+#define USACCUM_IBIT __USACCUM_IBIT__
+#else
+#define USACCUM_IBIT 8
+#endif // USACCUM_IBIT
+
+#define USACCUM_MIN 0.0UHK
+
+#ifdef __USACCUM_MAX__
+#define USACCUM_MAX __USACCUM_MAX__
+#else
+#define USACCUM_MAX 0x1.FFFEp+7UHK
+#endif // USACCUM_MAX
+
+#ifdef __USACCUM_EPSILON__
+#define USACCUM_EPSILON __USACCUM_EPSILON__
+#else
+#define USACCUM_EPSILON 0x1.0p-8UHK
+#endif // USACCUM_EPSILON
+
+#ifdef __ACCUM_FBIT__
+#define ACCUM_FBIT __ACCUM_FBIT__
+#else
+#define ACCUM_FBIT 15
+#endif // ACCUM_FBIT
+
+#ifdef __ACCUM_IBIT__
+#define ACCUM_IBIT __ACCUM_IBIT__
+#else
+#define ACCUM_IBIT 16
+#endif // ACCUM_IBIT
+
+#ifdef __ACCUM_MIN__
+#define ACCUM_MIN __ACCUM_MIN__
+#else
+#define ACCUM_MIN (-0x1.0p+15K - 0x1.0p+15K)
+#endif // ACCUM_MIN
+
+#ifdef __ACCUM_MAX__
+#define ACCUM_MAX __ACCUM_MAX__
+#else
+#define ACCUM_MAX 0x1.FFFFFFFCp+15K
+#endif // ACCUM_MAX
+
+#ifdef __ACCUM_EPSILON__
+#define ACCUM_EPSILON __ACCUM_EPSILON__
+#else
+#define ACCUM_EPSILON 0x1.0p-15K
+#endif // ACCUM_EPSILON
+
+#ifdef __UACCUM_FBIT__
+#define UACCUM_FBIT __UACCUM_FBIT__
+#else
+#define UACCUM_FBIT 16
+#endif // UACCUM_FBIT
+
+#ifdef __UACCUM_IBIT__
+#define UACCUM_IBIT __UACCUM_IBIT__
+#else
+#define UACCUM_IBIT 16
+#endif // UACCUM_IBIT
+
+#define UACCUM_MIN 0.0UK
+
+#ifdef __UACCUM_MAX__
+#define UACCUM_MAX __UACCUM_MAX__
+#else
+#define UACCUM_MAX 0x1.FFFFFFFEp+15UK
+#endif // UACCUM_MAX
+
+#ifdef __UACCUM_EPSILON__
+#define UACCUM_EPSILON __UACCUM_EPSILON__
+#else
+#define UACCUM_EPSILON 0x1.0p-16UK
+#endif // UACCUM_EPSILON
+
+#ifdef __LACCUM_FBIT__
+#define LACCUM_FBIT __LACCUM_FBIT__
+#else
+#define LACCUM_FBIT 31
+#endif // LACCUM_FBIT
+
+#ifdef __LACCUM_IBIT__
+#define LACCUM_IBIT __LACCUM_IBIT__
+#else
+#define LACCUM_IBIT 32
+#endif // LACCUM_IBIT
+
+#ifdef __LACCUM_MIN__
+#define LACCUM_MIN __LACCUM_MIN__
+#else
+#define LACCUM_MIN (-0x1.0p+31LK - 0x1.0p+31LK)
+#endif // LACCUM_MIN
+
+#ifdef __LACCUM_MAX__
+#define LACCUM_MAX __LACCUM_MAX__
+#else
+#define LACCUM_MAX 0x1.FFFFFFFFFFFFFFFCp+31LK
+#endif // LACCUM_MAX
+
+#ifdef __LACCUM_EPSILON__
+#define LACCUM_EPSILON __LACCUM_EPSILON__
+#else
+#define LACCUM_EPSILON 0x1.0p-31LK
+#endif // LACCUM_EPSILON
+
+#ifdef __ULACCUM_FBIT__
+#define ULACCUM_FBIT __ULACCUM_FBIT__
+#else
+#define ULACCUM_FBIT 32
+#endif // ULACCUM_FBIT
+
+#ifdef __ULACCUM_IBIT__
+#define ULACCUM_IBIT __ULACCUM_IBIT__
+#else
+#define ULACCUM_IBIT 32
+#endif // ULACCUM_IBIT
+
+#define ULACCUM_MIN 0.0ULK
+
+#ifdef __ULACCUM_MAX__
+#define ULACCUM_MAX __ULACCUM_MAX__
+#else
+#define ULACCUM_MAX 0x1.FFFFFFFFFFFFFFFEp+31ULK
+#endif // ULACCUM_MAX
+
+#ifdef __ULACCUM_EPSILON__
+#define ULACCUM_EPSILON __ULACCUM_EPSILON__
+#else
+#define ULACCUM_EPSILON 0x1.0p-32ULK
+#endif // ULACCUM_EPSILON
+
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
+#endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
diff --git a/include/llvm-libc-macros/stdint-macros.h b/include/llvm-libc-macros/stdint-macros.h
new file mode 100644
index 000000000000..1d5da2b783b6
--- /dev/null
+++ b/include/llvm-libc-macros/stdint-macros.h
@@ -0,0 +1,878 @@
+//===-- Definition of macros from stdint.h --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_STDINT_MACROS_H
+#define LLVM_LIBC_MACROS_STDINT_MACROS_H
+
+// These definitions are copied directly from the clang implementation located
+// at 'clang/lib/Headers/stdint.h'. We provide it here again for compatibility.
+
+/* C99 7.18.1.1 Exact-width integer types.
+ * C99 7.18.1.2 Minimum-width integer types.
+ * C99 7.18.1.3 Fastest minimum-width integer types.
+ *
+ * The standard requires that exact-width type be defined for 8-, 16-, 32-, and
+ * 64-bit types if they are implemented. Other exact width types are optional.
+ * This implementation defines an exact-width types for every integer width
+ * that is represented in the standard integer types.
+ *
+ * The standard also requires minimum-width types be defined for 8-, 16-, 32-,
+ * and 64-bit widths regardless of whether there are corresponding exact-width
+ * types.
+ *
+ * To accommodate targets that are missing types that are exactly 8, 16, 32, or
+ * 64 bits wide, this implementation takes an approach of cascading
+ * redefinitions, redefining __int_leastN_t to successively smaller exact-width
+ * types. It is therefore important that the types are defined in order of
+ * descending widths.
+ *
+ * We currently assume that the minimum-width types and the fastest
+ * minimum-width types are the same. This is allowed by the standard, but is
+ * suboptimal.
+ *
+ * In violation of the standard, some targets do not implement a type that is
+ * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit).
+ * To accommodate these targets, a required minimum-width type is only
+ * defined if there exists an exact-width type of equal or greater width.
+ */
+
+#ifdef __INT64_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef __INT64_TYPE__ int64_t;
+#endif /* __int8_t_defined */
+typedef __UINT64_TYPE__ uint64_t;
+#undef __int_least64_t
+#define __int_least64_t int64_t
+#undef __uint_least64_t
+#define __uint_least64_t uint64_t
+#undef __int_least32_t
+#define __int_least32_t int64_t
+#undef __uint_least32_t
+#define __uint_least32_t uint64_t
+#undef __int_least16_t
+#define __int_least16_t int64_t
+#undef __uint_least16_t
+#define __uint_least16_t uint64_t
+#undef __int_least8_t
+#define __int_least8_t int64_t
+#undef __uint_least8_t
+#define __uint_least8_t uint64_t
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+typedef __INT56_TYPE__ int56_t;
+typedef __UINT56_TYPE__ uint56_t;
+typedef int56_t int_least56_t;
+typedef uint56_t uint_least56_t;
+typedef int56_t int_fast56_t;
+typedef uint56_t uint_fast56_t;
+#undef __int_least32_t
+#define __int_least32_t int56_t
+#undef __uint_least32_t
+#define __uint_least32_t uint56_t
+#undef __int_least16_t
+#define __int_least16_t int56_t
+#undef __uint_least16_t
+#define __uint_least16_t uint56_t
+#undef __int_least8_t
+#define __int_least8_t int56_t
+#undef __uint_least8_t
+#define __uint_least8_t uint56_t
+#endif /* __INT56_TYPE__ */
+
+#ifdef __INT48_TYPE__
+typedef __INT48_TYPE__ int48_t;
+typedef __UINT48_TYPE__ uint48_t;
+typedef int48_t int_least48_t;
+typedef uint48_t uint_least48_t;
+typedef int48_t int_fast48_t;
+typedef uint48_t uint_fast48_t;
+#undef __int_least32_t
+#define __int_least32_t int48_t
+#undef __uint_least32_t
+#define __uint_least32_t uint48_t
+#undef __int_least16_t
+#define __int_least16_t int48_t
+#undef __uint_least16_t
+#define __uint_least16_t uint48_t
+#undef __int_least8_t
+#define __int_least8_t int48_t
+#undef __uint_least8_t
+#define __uint_least8_t uint48_t
+#endif /* __INT48_TYPE__ */
+
+#ifdef __INT40_TYPE__
+typedef __INT40_TYPE__ int40_t;
+typedef __UINT40_TYPE__ uint40_t;
+typedef int40_t int_least40_t;
+typedef uint40_t uint_least40_t;
+typedef int40_t int_fast40_t;
+typedef uint40_t uint_fast40_t;
+#undef __int_least32_t
+#define __int_least32_t int40_t
+#undef __uint_least32_t
+#define __uint_least32_t uint40_t
+#undef __int_least16_t
+#define __int_least16_t int40_t
+#undef __uint_least16_t
+#define __uint_least16_t uint40_t
+#undef __int_least8_t
+#define __int_least8_t int40_t
+#undef __uint_least8_t
+#define __uint_least8_t uint40_t
+#endif /* __INT40_TYPE__ */
+
+#ifdef __INT32_TYPE__
+
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef __INT32_TYPE__ int32_t;
+#endif /* __int8_t_defined */
+
+#ifndef __uint32_t_defined /* more glibc compatibility */
+#define __uint32_t_defined
+typedef __UINT32_TYPE__ uint32_t;
+#endif /* __uint32_t_defined */
+
+#undef __int_least32_t
+#define __int_least32_t int32_t
+#undef __uint_least32_t
+#define __uint_least32_t uint32_t
+#undef __int_least16_t
+#define __int_least16_t int32_t
+#undef __uint_least16_t
+#define __uint_least16_t uint32_t
+#undef __int_least8_t
+#define __int_least8_t int32_t
+#undef __uint_least8_t
+#define __uint_least8_t uint32_t
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+typedef __INT24_TYPE__ int24_t;
+typedef __UINT24_TYPE__ uint24_t;
+typedef int24_t int_least24_t;
+typedef uint24_t uint_least24_t;
+typedef int24_t int_fast24_t;
+typedef uint24_t uint_fast24_t;
+#undef __int_least16_t
+#define __int_least16_t int24_t
+#undef __uint_least16_t
+#define __uint_least16_t uint24_t
+#undef __int_least8_t
+#define __int_least8_t int24_t
+#undef __uint_least8_t
+#define __uint_least8_t uint24_t
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
+typedef __UINT16_TYPE__ uint16_t;
+#undef __int_least16_t
+#define __int_least16_t int16_t
+#undef __uint_least16_t
+#define __uint_least16_t uint16_t
+#undef __int_least8_t
+#define __int_least8_t int16_t
+#undef __uint_least8_t
+#define __uint_least8_t uint16_t
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/
+typedef __INT8_TYPE__ int8_t;
+#endif /* __int8_t_defined */
+typedef __UINT8_TYPE__ uint8_t;
+#undef __int_least8_t
+#define __int_least8_t int8_t
+#undef __uint_least8_t
+#define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
+/* prevent glibc sys/types.h from defining conflicting types */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif /* __int8_t_defined */
+
+/* C99 7.18.1.4 Integer types capable of holding object pointers.
+ */
+#define __stdint_join3(a, b, c) a##b##c
+
+#ifndef _INTPTR_T
+#ifndef __intptr_t_defined
+typedef __INTPTR_TYPE__ intptr_t;
+#define __intptr_t_defined
+#define _INTPTR_T
+#endif
+#endif
+
+#ifndef _UINTPTR_T
+typedef __UINTPTR_TYPE__ uintptr_t;
+#define _UINTPTR_T
+#endif
+
+/* C99 7.18.1.5 Greatest-width integer types.
+ */
+typedef __INTMAX_TYPE__ intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+
+/* C99 7.18.4 Macros for minimum-width integer constants.
+ *
+ * The standard requires that integer constant macros be defined for all the
+ * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width
+ * types are required, the corresponding integer constant macros are defined
+ * here. This implementation also defines minimum-width types for every other
+ * integer width that the target implements, so corresponding macros are
+ * defined below, too.
+ *
+ * These macros are defined using the same successive-shrinking approach as
+ * the type definitions above. It is likewise important that macros are defined
+ * in order of decending width.
+ *
+ * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#define __int_c_join(a, b) a##b
+#define __int_c(v, suffix) __int_c_join(v, suffix)
+#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
+
+#ifdef __INT64_TYPE__
+#undef __int64_c_suffix
+#undef __int32_c_suffix
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT64_C_SUFFIX__
+#define __int64_c_suffix __INT64_C_SUFFIX__
+#define __int32_c_suffix __INT64_C_SUFFIX__
+#define __int16_c_suffix __INT64_C_SUFFIX__
+#define __int8_c_suffix __INT64_C_SUFFIX__
+#endif /* __INT64_C_SUFFIX__ */
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+#ifdef __int64_c_suffix
+#define INT64_C(v) __int_c(v, __int64_c_suffix)
+#define UINT64_C(v) __uint_c(v, __int64_c_suffix)
+#else
+#define INT64_C(v) v
+#define UINT64_C(v) v##U
+#endif /* __int64_c_suffix */
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+#undef __int32_c_suffix
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT56_C_SUFFIX__
+#define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__)
+#define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__)
+#define __int32_c_suffix __INT56_C_SUFFIX__
+#define __int16_c_suffix __INT56_C_SUFFIX__
+#define __int8_c_suffix __INT56_C_SUFFIX__
+#else
+#define INT56_C(v) v
+#define UINT56_C(v) v##U
+#endif /* __INT56_C_SUFFIX__ */
+#endif /* __INT56_TYPE__ */
+
+#ifdef __INT48_TYPE__
+#undef __int32_c_suffix
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT48_C_SUFFIX__
+#define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__)
+#define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__)
+#define __int32_c_suffix __INT48_C_SUFFIX__
+#define __int16_c_suffix __INT48_C_SUFFIX__
+#define __int8_c_suffix __INT48_C_SUFFIX__
+#else
+#define INT48_C(v) v
+#define UINT48_C(v) v##U
+#endif /* __INT48_C_SUFFIX__ */
+#endif /* __INT48_TYPE__ */
+
+#ifdef __INT40_TYPE__
+#undef __int32_c_suffix
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT40_C_SUFFIX__
+#define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__)
+#define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__)
+#define __int32_c_suffix __INT40_C_SUFFIX__
+#define __int16_c_suffix __INT40_C_SUFFIX__
+#define __int8_c_suffix __INT40_C_SUFFIX__
+#else
+#define INT40_C(v) v
+#define UINT40_C(v) v##U
+#endif /* __INT40_C_SUFFIX__ */
+#endif /* __INT40_TYPE__ */
+
+#ifdef __INT32_TYPE__
+#undef __int32_c_suffix
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT32_C_SUFFIX__
+#define __int32_c_suffix __INT32_C_SUFFIX__
+#define __int16_c_suffix __INT32_C_SUFFIX__
+#define __int8_c_suffix __INT32_C_SUFFIX__
+#endif /* __INT32_C_SUFFIX__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+#ifdef __int32_c_suffix
+#define INT32_C(v) __int_c(v, __int32_c_suffix)
+#define UINT32_C(v) __uint_c(v, __int32_c_suffix)
+#else
+#define INT32_C(v) v
+#define UINT32_C(v) v##U
+#endif /* __int32_c_suffix */
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT24_C_SUFFIX__
+#define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__)
+#define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__)
+#define __int16_c_suffix __INT24_C_SUFFIX__
+#define __int8_c_suffix __INT24_C_SUFFIX__
+#else
+#define INT24_C(v) v
+#define UINT24_C(v) v##U
+#endif /* __INT24_C_SUFFIX__ */
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#undef __int16_c_suffix
+#undef __int8_c_suffix
+#ifdef __INT16_C_SUFFIX__
+#define __int16_c_suffix __INT16_C_SUFFIX__
+#define __int8_c_suffix __INT16_C_SUFFIX__
+#endif /* __INT16_C_SUFFIX__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+#ifdef __int16_c_suffix
+#define INT16_C(v) __int_c(v, __int16_c_suffix)
+#define UINT16_C(v) __uint_c(v, __int16_c_suffix)
+#else
+#define INT16_C(v) v
+#define UINT16_C(v) v##U
+#endif /* __int16_c_suffix */
+#endif /* __int_least16_t */
+
+#ifdef __INT8_TYPE__
+#undef __int8_c_suffix
+#ifdef __INT8_C_SUFFIX__
+#define __int8_c_suffix __INT8_C_SUFFIX__
+#endif /* __INT8_C_SUFFIX__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+#ifdef __int8_c_suffix
+#define INT8_C(v) __int_c(v, __int8_c_suffix)
+#define UINT8_C(v) __uint_c(v, __int8_c_suffix)
+#else
+#define INT8_C(v) v
+#define UINT8_C(v) v##U
+#endif /* __int8_c_suffix */
+#endif /* __int_least8_t */
+
+/* C99 7.18.2.1 Limits of exact-width integer types.
+ * C99 7.18.2.2 Limits of minimum-width integer types.
+ * C99 7.18.2.3 Limits of fastest minimum-width integer types.
+ *
+ * The presence of limit macros are completely optional in C99. This
+ * implementation defines limits for all of the types (exact- and
+ * minimum-width) that it defines above, using the limits of the minimum-width
+ * type for any types that do not have exact-width representations.
+ *
+ * As in the type definitions, this section takes an approach of
+ * successive-shrinking to determine which limits to use for the standard (8,
+ * 16, 32, 64) bit widths when they don't have exact representations. It is
+ * therefore important that the definitions be kept in order of decending
+ * widths.
+ *
+ * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#ifdef __INT64_TYPE__
+#define INT64_MAX INT64_C(9223372036854775807)
+#define INT64_MIN (-INT64_C(9223372036854775807) - 1)
+#define UINT64_MAX UINT64_C(18446744073709551615)
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT64_WIDTH 64
+#define INT64_WIDTH UINT64_WIDTH
+
+#define __UINT_LEAST64_WIDTH UINT64_WIDTH
+#undef __UINT_LEAST32_WIDTH
+#define __UINT_LEAST32_WIDTH UINT64_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT64_WIDTH
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT64_MAX
+#endif /* __STDC_VERSION__ */
+
+#define __INT_LEAST64_MIN INT64_MIN
+#define __INT_LEAST64_MAX INT64_MAX
+#define __UINT_LEAST64_MAX UINT64_MAX
+#undef __INT_LEAST32_MIN
+#define __INT_LEAST32_MIN INT64_MIN
+#undef __INT_LEAST32_MAX
+#define __INT_LEAST32_MAX INT64_MAX
+#undef __UINT_LEAST32_MAX
+#define __UINT_LEAST32_MAX UINT64_MAX
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT64_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT64_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT64_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT64_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT64_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT64_MAX
+#endif /* __INT64_TYPE__ */
+
+#ifdef __INT_LEAST64_MIN
+#define INT_LEAST64_MIN __INT_LEAST64_MIN
+#define INT_LEAST64_MAX __INT_LEAST64_MAX
+#define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+#define INT_FAST64_MIN __INT_LEAST64_MIN
+#define INT_FAST64_MAX __INT_LEAST64_MAX
+#define UINT_FAST64_MAX __UINT_LEAST64_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT_LEAST64_WIDTH __UINT_LEAST64_WIDTH
+#define INT_LEAST64_WIDTH UINT_LEAST64_WIDTH
+#define UINT_FAST64_WIDTH __UINT_LEAST64_WIDTH
+#define INT_FAST64_WIDTH UINT_FAST64_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT_LEAST64_MIN */
+
+#ifdef __INT56_TYPE__
+#define INT56_MAX INT56_C(36028797018963967)
+#define INT56_MIN (-INT56_C(36028797018963967) - 1)
+#define UINT56_MAX UINT56_C(72057594037927935)
+#define INT_LEAST56_MIN INT56_MIN
+#define INT_LEAST56_MAX INT56_MAX
+#define UINT_LEAST56_MAX UINT56_MAX
+#define INT_FAST56_MIN INT56_MIN
+#define INT_FAST56_MAX INT56_MAX
+#define UINT_FAST56_MAX UINT56_MAX
+
+#undef __INT_LEAST32_MIN
+#define __INT_LEAST32_MIN INT56_MIN
+#undef __INT_LEAST32_MAX
+#define __INT_LEAST32_MAX INT56_MAX
+#undef __UINT_LEAST32_MAX
+#define __UINT_LEAST32_MAX UINT56_MAX
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT56_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT56_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT56_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT56_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT56_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT56_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT56_WIDTH 56
+#define INT56_WIDTH UINT56_WIDTH
+#define UINT_LEAST56_WIDTH UINT56_WIDTH
+#define INT_LEAST56_WIDTH UINT_LEAST56_WIDTH
+#define UINT_FAST56_WIDTH UINT56_WIDTH
+#define INT_FAST56_WIDTH UINT_FAST56_WIDTH
+#undef __UINT_LEAST32_WIDTH
+#define __UINT_LEAST32_WIDTH UINT56_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT56_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT56_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT56_TYPE__ */
+
+#ifdef __INT48_TYPE__
+#define INT48_MAX INT48_C(140737488355327)
+#define INT48_MIN (-INT48_C(140737488355327) - 1)
+#define UINT48_MAX UINT48_C(281474976710655)
+#define INT_LEAST48_MIN INT48_MIN
+#define INT_LEAST48_MAX INT48_MAX
+#define UINT_LEAST48_MAX UINT48_MAX
+#define INT_FAST48_MIN INT48_MIN
+#define INT_FAST48_MAX INT48_MAX
+#define UINT_FAST48_MAX UINT48_MAX
+
+#undef __INT_LEAST32_MIN
+#define __INT_LEAST32_MIN INT48_MIN
+#undef __INT_LEAST32_MAX
+#define __INT_LEAST32_MAX INT48_MAX
+#undef __UINT_LEAST32_MAX
+#define __UINT_LEAST32_MAX UINT48_MAX
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT48_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT48_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT48_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT48_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT48_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT48_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT48_WIDTH 48
+#define INT48_WIDTH UINT48_WIDTH
+#define UINT_LEAST48_WIDTH UINT48_WIDTH
+#define INT_LEAST48_WIDTH UINT_LEAST48_WIDTH
+#define UINT_FAST48_WIDTH UINT48_WIDTH
+#define INT_FAST48_WIDTH UINT_FAST48_WIDTH
+#undef __UINT_LEAST32_WIDTH
+#define __UINT_LEAST32_WIDTH UINT48_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT48_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT48_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT48_TYPE__ */
+
+#ifdef __INT40_TYPE__
+#define INT40_MAX INT40_C(549755813887)
+#define INT40_MIN (-INT40_C(549755813887) - 1)
+#define UINT40_MAX UINT40_C(1099511627775)
+#define INT_LEAST40_MIN INT40_MIN
+#define INT_LEAST40_MAX INT40_MAX
+#define UINT_LEAST40_MAX UINT40_MAX
+#define INT_FAST40_MIN INT40_MIN
+#define INT_FAST40_MAX INT40_MAX
+#define UINT_FAST40_MAX UINT40_MAX
+
+#undef __INT_LEAST32_MIN
+#define __INT_LEAST32_MIN INT40_MIN
+#undef __INT_LEAST32_MAX
+#define __INT_LEAST32_MAX INT40_MAX
+#undef __UINT_LEAST32_MAX
+#define __UINT_LEAST32_MAX UINT40_MAX
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT40_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT40_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT40_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT40_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT40_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT40_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT40_WIDTH 40
+#define INT40_WIDTH UINT40_WIDTH
+#define UINT_LEAST40_WIDTH UINT40_WIDTH
+#define INT_LEAST40_WIDTH UINT_LEAST40_WIDTH
+#define UINT_FAST40_WIDTH UINT40_WIDTH
+#define INT_FAST40_WIDTH UINT_FAST40_WIDTH
+#undef __UINT_LEAST32_WIDTH
+#define __UINT_LEAST32_WIDTH UINT40_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT40_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT40_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT40_TYPE__ */
+
+#ifdef __INT32_TYPE__
+#define INT32_MAX INT32_C(2147483647)
+#define INT32_MIN (-INT32_C(2147483647) - 1)
+#define UINT32_MAX UINT32_C(4294967295)
+
+#undef __INT_LEAST32_MIN
+#define __INT_LEAST32_MIN INT32_MIN
+#undef __INT_LEAST32_MAX
+#define __INT_LEAST32_MAX INT32_MAX
+#undef __UINT_LEAST32_MAX
+#define __UINT_LEAST32_MAX UINT32_MAX
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT32_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT32_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT32_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT32_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT32_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT32_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT32_WIDTH 32
+#define INT32_WIDTH UINT32_WIDTH
+#undef __UINT_LEAST32_WIDTH
+#define __UINT_LEAST32_WIDTH UINT32_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT32_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT32_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT_LEAST32_MIN
+#define INT_LEAST32_MIN __INT_LEAST32_MIN
+#define INT_LEAST32_MAX __INT_LEAST32_MAX
+#define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+#define INT_FAST32_MIN __INT_LEAST32_MIN
+#define INT_FAST32_MAX __INT_LEAST32_MAX
+#define UINT_FAST32_MAX __UINT_LEAST32_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT_LEAST32_WIDTH __UINT_LEAST32_WIDTH
+#define INT_LEAST32_WIDTH UINT_LEAST32_WIDTH
+#define UINT_FAST32_WIDTH __UINT_LEAST32_WIDTH
+#define INT_FAST32_WIDTH UINT_FAST32_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT_LEAST32_MIN */
+
+#ifdef __INT24_TYPE__
+#define INT24_MAX INT24_C(8388607)
+#define INT24_MIN (-INT24_C(8388607) - 1)
+#define UINT24_MAX UINT24_C(16777215)
+#define INT_LEAST24_MIN INT24_MIN
+#define INT_LEAST24_MAX INT24_MAX
+#define UINT_LEAST24_MAX UINT24_MAX
+#define INT_FAST24_MIN INT24_MIN
+#define INT_FAST24_MAX INT24_MAX
+#define UINT_FAST24_MAX UINT24_MAX
+
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT24_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT24_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT24_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT24_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT24_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT24_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT24_WIDTH 24
+#define INT24_WIDTH UINT24_WIDTH
+#define UINT_LEAST24_WIDTH UINT24_WIDTH
+#define INT_LEAST24_WIDTH UINT_LEAST24_WIDTH
+#define UINT_FAST24_WIDTH UINT24_WIDTH
+#define INT_FAST24_WIDTH UINT_FAST24_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT24_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT24_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#define INT16_MAX INT16_C(32767)
+#define INT16_MIN (-INT16_C(32767) - 1)
+#define UINT16_MAX UINT16_C(65535)
+
+#undef __INT_LEAST16_MIN
+#define __INT_LEAST16_MIN INT16_MIN
+#undef __INT_LEAST16_MAX
+#define __INT_LEAST16_MAX INT16_MAX
+#undef __UINT_LEAST16_MAX
+#define __UINT_LEAST16_MAX UINT16_MAX
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT16_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT16_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT16_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT16_WIDTH 16
+#define INT16_WIDTH UINT16_WIDTH
+#undef __UINT_LEAST16_WIDTH
+#define __UINT_LEAST16_WIDTH UINT16_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT16_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT_LEAST16_MIN
+#define INT_LEAST16_MIN __INT_LEAST16_MIN
+#define INT_LEAST16_MAX __INT_LEAST16_MAX
+#define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+#define INT_FAST16_MIN __INT_LEAST16_MIN
+#define INT_FAST16_MAX __INT_LEAST16_MAX
+#define UINT_FAST16_MAX __UINT_LEAST16_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT_LEAST16_WIDTH __UINT_LEAST16_WIDTH
+#define INT_LEAST16_WIDTH UINT_LEAST16_WIDTH
+#define UINT_FAST16_WIDTH __UINT_LEAST16_WIDTH
+#define INT_FAST16_WIDTH UINT_FAST16_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT_LEAST16_MIN */
+
+#ifdef __INT8_TYPE__
+#define INT8_MAX INT8_C(127)
+#define INT8_MIN (-INT8_C(127) - 1)
+#define UINT8_MAX UINT8_C(255)
+
+#undef __INT_LEAST8_MIN
+#define __INT_LEAST8_MIN INT8_MIN
+#undef __INT_LEAST8_MAX
+#define __INT_LEAST8_MAX INT8_MAX
+#undef __UINT_LEAST8_MAX
+#define __UINT_LEAST8_MAX UINT8_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT8_WIDTH 8
+#define INT8_WIDTH UINT8_WIDTH
+#undef __UINT_LEAST8_WIDTH
+#define __UINT_LEAST8_WIDTH UINT8_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __INT_LEAST8_MIN
+#define INT_LEAST8_MIN __INT_LEAST8_MIN
+#define INT_LEAST8_MAX __INT_LEAST8_MAX
+#define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+#define INT_FAST8_MIN __INT_LEAST8_MIN
+#define INT_FAST8_MAX __INT_LEAST8_MAX
+#define UINT_FAST8_MAX __UINT_LEAST8_MAX
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define UINT_LEAST8_WIDTH __UINT_LEAST8_WIDTH
+#define INT_LEAST8_WIDTH UINT_LEAST8_WIDTH
+#define UINT_FAST8_WIDTH __UINT_LEAST8_WIDTH
+#define INT_FAST8_WIDTH UINT_FAST8_WIDTH
+#endif /* __STDC_VERSION__ */
+#endif /* __INT_LEAST8_MIN */
+
+/* Some utility macros */
+#define __INTN_MIN(n) __stdint_join3(INT, n, _MIN)
+#define __INTN_MAX(n) __stdint_join3(INT, n, _MAX)
+#define __UINTN_MAX(n) __stdint_join3(UINT, n, _MAX)
+#define __INTN_C(n, v) __stdint_join3(INT, n, _C(v))
+#define __UINTN_C(n, v) __stdint_join3(UINT, n, _C(v))
+
+/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
+/* C99 7.18.3 Limits of other integer types. */
+
+#define INTPTR_MIN (-__INTPTR_MAX__ - 1)
+#define INTPTR_MAX __INTPTR_MAX__
+#define UINTPTR_MAX __UINTPTR_MAX__
+#define PTRDIFF_MIN (-__PTRDIFF_MAX__ - 1)
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define SIZE_MAX __SIZE_MAX__
+
+/* C23 7.22.2.4 Width of integer types capable of holding object pointers. */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+/* NB: The C standard requires that these be the same value, but the compiler
+ exposes separate internal width macros. */
+#define INTPTR_WIDTH __INTPTR_WIDTH__
+#define UINTPTR_WIDTH __UINTPTR_WIDTH__
+#endif
+
+/* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__
+ * is enabled. */
+#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
+#define RSIZE_MAX (SIZE_MAX >> 1)
+#endif
+
+/* C99 7.18.2.5 Limits of greatest-width integer types. */
+#define INTMAX_MIN (-__INTMAX_MAX__ - 1)
+#define INTMAX_MAX __INTMAX_MAX__
+#define UINTMAX_MAX __UINTMAX_MAX__
+
+/* C23 7.22.2.5 Width of greatest-width integer types. */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+/* NB: The C standard requires that these be the same value, but the compiler
+ exposes separate internal width macros. */
+#define INTMAX_WIDTH __INTMAX_WIDTH__
+#define UINTMAX_WIDTH __UINTMAX_WIDTH__
+#endif
+
+/* C99 7.18.3 Limits of other integer types. */
+#define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__)
+#define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__)
+#ifdef __WINT_UNSIGNED__
+#define WINT_MIN __UINTN_C(__WINT_WIDTH__, 0)
+#define WINT_MAX __UINTN_MAX(__WINT_WIDTH__)
+#else
+#define WINT_MIN __INTN_MIN(__WINT_WIDTH__)
+#define WINT_MAX __INTN_MAX(__WINT_WIDTH__)
+#endif
+
+#ifndef WCHAR_MAX
+#define WCHAR_MAX __WCHAR_MAX__
+#endif
+#ifndef WCHAR_MIN
+#if __WCHAR_MAX__ == __INTN_MAX(__WCHAR_WIDTH__)
+#define WCHAR_MIN __INTN_MIN(__WCHAR_WIDTH__)
+#else
+#define WCHAR_MIN __UINTN_C(__WCHAR_WIDTH__, 0)
+#endif
+#endif
+
+/* 7.18.4.2 Macros for greatest-width integer constants. */
+#define INTMAX_C(v) __int_c(v, __INTMAX_C_SUFFIX__)
+#define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__)
+
+/* C23 7.22.3.x Width of other integer types. */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
+#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
+#define SIZE_WIDTH __SIZE_WIDTH__
+#define WCHAR_WIDTH __WCHAR_WIDTH__
+#define WINT_WIDTH __WINT_WIDTH__
+#endif
+#endif // LLVM_LIBC_MACROS_STDINT_MACROS_H
diff --git a/include/llvm-libc-macros/stdio-macros.h b/include/llvm-libc-macros/stdio-macros.h
index b2c62ec7cff2..4664801c5731 100644
--- a/include/llvm-libc-macros/stdio-macros.h
+++ b/include/llvm-libc-macros/stdio-macros.h
@@ -6,9 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_STDIO_MACROS_H
-#define __LLVM_LIBC_MACROS_STDIO_MACROS_H
+#ifndef LLVM_LIBC_MACROS_STDIO_MACROS_H
+#define LLVM_LIBC_MACROS_STDIO_MACROS_H
+
+#ifndef EOF
+#define EOF (-1)
+#endif
#define BUFSIZ 1024
-#endif // __LLVM_LIBC_MACROS_STDIO_MACROS_H
+#endif // LLVM_LIBC_MACROS_STDIO_MACROS_H
diff --git a/include/llvm-libc-macros/stdlib-macros.h b/include/llvm-libc-macros/stdlib-macros.h
index a7625aa187c9..5fcbfef97b32 100644
--- a/include/llvm-libc-macros/stdlib-macros.h
+++ b/include/llvm-libc-macros/stdlib-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_STDLIB_MACROS_H
-#define __LLVM_LIBC_MACROS_STDLIB_MACROS_H
+#ifndef LLVM_LIBC_MACROS_STDLIB_MACROS_H
+#define LLVM_LIBC_MACROS_STDLIB_MACROS_H
#ifndef NULL
#define __need_NULL
@@ -19,4 +19,4 @@
#define RAND_MAX 2147483647
-#endif // __LLVM_LIBC_MACROS_STDLIB_MACROS_H
+#endif // LLVM_LIBC_MACROS_STDLIB_MACROS_H
diff --git a/include/llvm-libc-macros/sys-auxv-macros.h b/include/llvm-libc-macros/sys-auxv-macros.h
index a57c6018ea0a..2dcaa2f1a8ee 100644
--- a/include/llvm-libc-macros/sys-auxv-macros.h
+++ b/include/llvm-libc-macros/sys-auxv-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_AUXV_MACROS_H
-#define __LLVM_LIBC_MACROS_AUXV_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_AUXV_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_AUXV_MACROS_H
// Macros defining the aux vector indexes.
#define AT_NULL 0
@@ -40,4 +40,4 @@
#define AT_MINSIGSTKSZ 51
#endif
-#endif // __LLVM_LIBC_MACROS_AUXV_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_AUXV_MACROS_H
diff --git a/include/llvm-libc-macros/sys-ioctl-macros.h b/include/llvm-libc-macros/sys-ioctl-macros.h
index c273fab36e3f..4a5f9651231f 100644
--- a/include/llvm-libc-macros/sys-ioctl-macros.h
+++ b/include/llvm-libc-macros/sys-ioctl-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
#ifdef __linux__
#include "linux/sys-ioctl-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_IOCTL_MACROS_H
diff --git a/include/llvm-libc-macros/sys-mman-macros.h b/include/llvm-libc-macros/sys-mman-macros.h
index 4ffc112f4e4d..a6dc6d96b5b7 100644
--- a/include/llvm-libc-macros/sys-mman-macros.h
+++ b/include/llvm-libc-macros/sys-mman-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
// Use definitions from <linux/mman.h> to dispatch arch-specific flag values.
// For example, MCL_CURRENT/MCL_FUTURE/MCL_ONFAULT are different on different
@@ -45,4 +45,4 @@
#define POSIX_MADV_DONTNEED MADV_DONTNEED
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_MMAN_MACROS_H
diff --git a/include/llvm-libc-macros/sys-queue-macros.h b/include/llvm-libc-macros/sys-queue-macros.h
index 59e6a9a392c9..089b6abaa024 100644
--- a/include/llvm-libc-macros/sys-queue-macros.h
+++ b/include/llvm-libc-macros/sys-queue-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
-#include <llvm-libc-macros/containerof-macro.h>
-#include <llvm-libc-macros/null-macro.h>
+#include "llvm-libc-macros/containerof-macro.h"
+#include "llvm-libc-macros/null-macro.h"
#ifdef __cplusplus
#define QUEUE_TYPEOF(type) type
@@ -22,12 +22,12 @@
#define SLIST_HEAD(name, type) \
struct name { \
- struct type *first; \
+ struct type *slh_first; \
}
#define SLIST_CLASS_HEAD(name, type) \
struct name { \
- class type *first; \
+ class type *slh_first; \
}
#define SLIST_HEAD_INITIALIZER(head) \
@@ -45,8 +45,8 @@
// Singly-linked list access methods.
-#define SLIST_EMPTY(head) ((head)->first == NULL)
-#define SLIST_FIRST(head) ((head)->first)
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_NEXT(elem, field) ((elem)->field.next)
#define SLIST_FOREACH(var, head, field) \
@@ -132,18 +132,18 @@
#define STAILQ_HEAD(name, type) \
struct name { \
- struct type *first; \
- struct type **last; \
+ struct type *stqh_first; \
+ struct type **stqh_last; \
}
#define STAILQ_CLASS_HEAD(name, type) \
struct name { \
- class type *first; \
- class type **last; \
+ class type *stqh_first; \
+ class type **stqh_last; \
}
#define STAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).first }
+ { NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
@@ -157,12 +157,12 @@
// Singly-linked tail queue access methods.
-#define STAILQ_EMPTY(head) ((head)->first == NULL)
-#define STAILQ_FIRST(head) ((head)->first)
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY(head) \
? NULL \
- : __containerof((head)->last, QUEUE_TYPEOF(type), field.next))
+ : __containerof((head)->stqh_last, QUEUE_TYPEOF(type), field.next))
#define STAILQ_NEXT(elem, field) ((elem)->field.next)
#define STAILQ_FOREACH(var, head, field) \
@@ -187,8 +187,8 @@
#define STAILQ_CONCAT(head1, head2, type, field) \
do { \
if (!STAILQ_EMPTY(head2)) { \
- *(head1)->last = (head2)->first; \
- (head1)->last = (head2)->last; \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT(head2); \
} \
} while (0)
@@ -196,28 +196,28 @@
#define STAILQ_INIT(head) \
do { \
STAILQ_FIRST(head) = NULL; \
- (head)->last = &STAILQ_FIRST(head); \
+ (head)->stqh_last = &STAILQ_FIRST(head); \
} while (0)
#define STAILQ_INSERT_AFTER(head, listelem, elem, field) \
do { \
if ((STAILQ_NEXT(elem, field) = STAILQ_NEXT(listelem, field)) == NULL) \
- (head)->last = &STAILQ_NEXT(elem, field); \
+ (head)->stqh_last = &STAILQ_NEXT(elem, field); \
STAILQ_NEXT(listelem, field) = (elem); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elem, field) \
do { \
if ((STAILQ_NEXT(elem, field) = STAILQ_FIRST(head)) == NULL) \
- (head)->last = &STAILQ_NEXT(elem, field); \
+ (head)->stqh_last = &STAILQ_NEXT(elem, field); \
STAILQ_FIRST(head) = (elem); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elem, field) \
do { \
STAILQ_NEXT(elem, field) = NULL; \
- *(head)->last = (elem); \
- (head)->last = &STAILQ_NEXT(elem, field); \
+ *(head)->stqh_last = (elem); \
+ (head)->stqh_last = &STAILQ_NEXT(elem, field); \
} while (0)
#define STAILQ_REMOVE(head, elem, type, field) \
@@ -236,27 +236,27 @@
do { \
if ((STAILQ_NEXT(elem, field) = \
STAILQ_NEXT(STAILQ_NEXT(elem, field), field)) == NULL) \
- (head)->last = &STAILQ_NEXT(elem, field); \
+ (head)->stqh_last = &STAILQ_NEXT(elem, field); \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) \
do { \
if ((STAILQ_FIRST(head) = STAILQ_NEXT(STAILQ_FIRST(head), field)) == NULL) \
- (head)->last = &STAILQ_FIRST(head); \
+ (head)->stqh_last = &STAILQ_FIRST(head); \
} while (0)
#define STAILQ_SWAP(head1, head2, type) \
do { \
QUEUE_TYPEOF(type) *first = STAILQ_FIRST(head1); \
- QUEUE_TYPEOF(type) **last = (head1)->last; \
+ QUEUE_TYPEOF(type) **last = (head1)->stqh_last; \
STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
- (head1)->last = (head2)->last; \
+ (head1)->stqh_last = (head2)->stqh_last; \
STAILQ_FIRST(head2) = first; \
- (head2)->last = last; \
+ (head2)->stqh_last = last; \
if (STAILQ_EMPTY(head1)) \
- (head1)->last = &STAILQ_FIRST(head1); \
+ (head1)->stqh_last = &STAILQ_FIRST(head1); \
if (STAILQ_EMPTY(head2)) \
- (head2)->last = &STAILQ_FIRST(head2); \
+ (head2)->stqh_last = &STAILQ_FIRST(head2); \
} while (0)
-#endif // __LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
diff --git a/include/llvm-libc-macros/sys-random-macros.h b/include/llvm-libc-macros/sys-random-macros.h
index e87128d0d0fc..9b1a8edb4f79 100644
--- a/include/llvm-libc-macros/sys-random-macros.h
+++ b/include/llvm-libc-macros/sys-random-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
#ifdef __linux__
#include "linux/sys-random-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
diff --git a/include/llvm-libc-macros/sys-resource-macros.h b/include/llvm-libc-macros/sys-resource-macros.h
index 272723a955a7..1ce01cdd1e83 100644
--- a/include/llvm-libc-macros/sys-resource-macros.h
+++ b/include/llvm-libc-macros/sys-resource-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
#ifdef __linux__
#include "linux/sys-resource-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
diff --git a/include/llvm-libc-macros/sys-select-macros.h b/include/llvm-libc-macros/sys-select-macros.h
index 5d6592c1c281..d54e5300d12e 100644
--- a/include/llvm-libc-macros/sys-select-macros.h
+++ b/include/llvm-libc-macros/sys-select-macros.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
#define FD_SETSIZE 1024
#define __FD_SET_WORD_TYPE unsigned long
@@ -32,4 +32,4 @@
#define FD_ISSET(fd, set) \
(int)(((set)->__set[__FD_WORD(fd)] & __FD_MASK(fd)) != 0)
-#endif // __LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_SELECT_MACROS_H
diff --git a/include/llvm-libc-macros/sys-socket-macros.h b/include/llvm-libc-macros/sys-socket-macros.h
index 203236099063..6b1d28070b43 100644
--- a/include/llvm-libc-macros/sys-socket-macros.h
+++ b/include/llvm-libc-macros/sys-socket-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
#ifdef __linux__
#include "linux/sys-socket-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_SOCKET_MACROS_H
diff --git a/include/llvm-libc-macros/sys-stat-macros.h b/include/llvm-libc-macros/sys-stat-macros.h
index 64f63c33b3e5..c47c9612705e 100644
--- a/include/llvm-libc-macros/sys-stat-macros.h
+++ b/include/llvm-libc-macros/sys-stat-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
#ifdef __linux__
#include "linux/sys-stat-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_STAT_MACROS_H
diff --git a/include/llvm-libc-macros/sys-time-macros.h b/include/llvm-libc-macros/sys-time-macros.h
index 8e4631703308..36d7d5adafc9 100644
--- a/include/llvm-libc-macros/sys-time-macros.h
+++ b/include/llvm-libc-macros/sys-time-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
#ifdef __linux__
#include "linux/sys-time-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_TIME_MACROS_H
diff --git a/include/llvm-libc-macros/sys-wait-macros.h b/include/llvm-libc-macros/sys-wait-macros.h
index ea58fccecaff..c418a7930b69 100644
--- a/include/llvm-libc-macros/sys-wait-macros.h
+++ b/include/llvm-libc-macros/sys-wait-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
-#define __LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
+#ifndef LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
#ifdef __linux__
#include "linux/sys-wait-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
+#endif // LLVM_LIBC_MACROS_SYS_WAIT_MACROS_H
diff --git a/include/llvm-libc-macros/termios-macros.h b/include/llvm-libc-macros/termios-macros.h
index c99982837a57..1067e8a57474 100644
--- a/include/llvm-libc-macros/termios-macros.h
+++ b/include/llvm-libc-macros/termios-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_TERMIOS_MACROS_H
-#define __LLVM_LIBC_MACROS_TERMIOS_MACROS_H
+#ifndef LLVM_LIBC_MACROS_TERMIOS_MACROS_H
+#define LLVM_LIBC_MACROS_TERMIOS_MACROS_H
#ifdef __linux__
#include "linux/termios-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_TERMIOS_MACROS_H
+#endif // LLVM_LIBC_MACROS_TERMIOS_MACROS_H
diff --git a/include/llvm-libc-macros/time-macros.h b/include/llvm-libc-macros/time-macros.h
index c3bd7aa24f56..6d49ed484d5d 100644
--- a/include/llvm-libc-macros/time-macros.h
+++ b/include/llvm-libc-macros/time-macros.h
@@ -1,5 +1,5 @@
-#ifndef __LLVM_LIBC_MACROS_TIME_MACROS_H
-#define __LLVM_LIBC_MACROS_TIME_MACROS_H
+#ifndef LLVM_LIBC_MACROS_TIME_MACROS_H
+#define LLVM_LIBC_MACROS_TIME_MACROS_H
#if defined(__AMDGPU__) || defined(__NVPTX__)
#include "gpu/time-macros.h"
@@ -7,4 +7,4 @@
#include "linux/time-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_TIME_MACROS_H
+#endif // LLVM_LIBC_MACROS_TIME_MACROS_H
diff --git a/include/llvm-libc-macros/unistd-macros.h b/include/llvm-libc-macros/unistd-macros.h
index dbcac0f5e72d..4f27f075fcc6 100644
--- a/include/llvm-libc-macros/unistd-macros.h
+++ b/include/llvm-libc-macros/unistd-macros.h
@@ -1,8 +1,8 @@
-#ifndef __LLVM_LIBC_MACROS_UNISTD_MACROS_H
-#define __LLVM_LIBC_MACROS_UNISTD_MACROS_H
+#ifndef LLVM_LIBC_MACROS_UNISTD_MACROS_H
+#define LLVM_LIBC_MACROS_UNISTD_MACROS_H
#ifdef __linux__
#include "linux/unistd-macros.h"
#endif
-#endif // __LLVM_LIBC_MACROS_UNISTD_MACROS_H
+#endif // LLVM_LIBC_MACROS_UNISTD_MACROS_H
diff --git a/include/llvm-libc-macros/wchar-macros.h b/include/llvm-libc-macros/wchar-macros.h
index adca41eb0122..5b211f5276b6 100644
--- a/include/llvm-libc-macros/wchar-macros.h
+++ b/include/llvm-libc-macros/wchar-macros.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_MACROS_WCHAR_MACROS_H
-#define __LLVM_LIBC_MACROS_WCHAR_MACROS_H
+#ifndef LLVM_LIBC_MACROS_WCHAR_MACROS_H
+#define LLVM_LIBC_MACROS_WCHAR_MACROS_H
#ifndef WEOF
#define WEOF 0xffffffffu
#endif
-#endif // __LLVM_LIBC_MACROS_WCHAR_MACROS_H
+#endif // LLVM_LIBC_MACROS_WCHAR_MACROS_H
diff --git a/include/llvm-libc-types/ACTION.h b/include/llvm-libc-types/ACTION.h
index 7181a59b177d..1ddce208df1c 100644
--- a/include/llvm-libc-types/ACTION.h
+++ b/include/llvm-libc-types/ACTION.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_ACTION_H__
-#define __LLVM_LIBC_TYPES_ACTION_H__
+#ifndef LLVM_LIBC_TYPES_ACTION_H
+#define LLVM_LIBC_TYPES_ACTION_H
typedef enum { FIND, ENTER } ACTION;
-#endif // __LLVM_LIBC_TYPES_ACTION_H__
+#endif // LLVM_LIBC_TYPES_ACTION_H
diff --git a/include/llvm-libc-types/DIR.h b/include/llvm-libc-types/DIR.h
index 0a2cf27d2485..855446db6f53 100644
--- a/include/llvm-libc-types/DIR.h
+++ b/include/llvm-libc-types/DIR.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_DIR_H__
-#define __LLVM_LIBC_TYPES_DIR_H__
+#ifndef LLVM_LIBC_TYPES_DIR_H
+#define LLVM_LIBC_TYPES_DIR_H
typedef struct DIR DIR;
-#endif // __LLVM_LIBC_TYPES_DIR_H__
+#endif // LLVM_LIBC_TYPES_DIR_H
diff --git a/include/llvm-libc-types/ENTRY.h b/include/llvm-libc-types/ENTRY.h
index 0ccb5938207a..ccbd777e2475 100644
--- a/include/llvm-libc-types/ENTRY.h
+++ b/include/llvm-libc-types/ENTRY.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_ENTRY_H__
-#define __LLVM_LIBC_TYPES_ENTRY_H__
+#ifndef LLVM_LIBC_TYPES_ENTRY_H
+#define LLVM_LIBC_TYPES_ENTRY_H
typedef struct {
char *key;
void *data;
} ENTRY;
-#endif // __LLVM_LIBC_TYPES_ENTRY_H__
+#endif // LLVM_LIBC_TYPES_ENTRY_H
diff --git a/include/llvm-libc-types/FILE.h b/include/llvm-libc-types/FILE.h
index 1c1ff97ec86a..f1d2e4f726c7 100644
--- a/include/llvm-libc-types/FILE.h
+++ b/include/llvm-libc-types/FILE.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FILE_H__
-#define __LLVM_LIBC_TYPES_FILE_H__
+#ifndef LLVM_LIBC_TYPES_FILE_H
+#define LLVM_LIBC_TYPES_FILE_H
typedef struct FILE FILE;
-#endif // __LLVM_LIBC_TYPES_FILE_H__
+#endif // LLVM_LIBC_TYPES_FILE_H
diff --git a/include/llvm-libc-types/__atexithandler_t.h b/include/llvm-libc-types/__atexithandler_t.h
index a9887b6abf70..01aed676c2a7 100644
--- a/include/llvm-libc-types/__atexithandler_t.h
+++ b/include/llvm-libc-types/__atexithandler_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_ATEXITHANDLER_T_H__
-#define __LLVM_LIBC_TYPES_ATEXITHANDLER_T_H__
+#ifndef LLVM_LIBC_TYPES___ATEXITHANDLER_T_H
+#define LLVM_LIBC_TYPES___ATEXITHANDLER_T_H
typedef void (*__atexithandler_t)(void);
-#endif // __LLVM_LIBC_TYPES_ATEXITHANDLER_T_H__
+#endif // LLVM_LIBC_TYPES___ATEXITHANDLER_T_H
diff --git a/include/llvm-libc-types/__atfork_callback_t.h b/include/llvm-libc-types/__atfork_callback_t.h
index 3da66c23feb0..ae2d0ca39d53 100644
--- a/include/llvm-libc-types/__atfork_callback_t.h
+++ b/include/llvm-libc-types/__atfork_callback_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_ATFORK_CALLBACK_T_H__
-#define __LLVM_LIBC_TYPES_ATFORK_CALLBACK_T_H__
+#ifndef LLVM_LIBC_TYPES___ATFORK_CALLBACK_T_H
+#define LLVM_LIBC_TYPES___ATFORK_CALLBACK_T_H
typedef void (*__atfork_callback_t)(void);
-#endif // __LLVM_LIBC_TYPES_ATFORK_CALLBACK_T_H__
+#endif // LLVM_LIBC_TYPES___ATFORK_CALLBACK_T_H
diff --git a/include/llvm-libc-types/__bsearchcompare_t.h b/include/llvm-libc-types/__bsearchcompare_t.h
index 40ebc7f35668..0b1987be1fdd 100644
--- a/include/llvm-libc-types/__bsearchcompare_t.h
+++ b/include/llvm-libc-types/__bsearchcompare_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_BSEARCHCOMPARE_T_H__
-#define __LLVM_LIBC_TYPES_BSEARCHCOMPARE_T_H__
+#ifndef LLVM_LIBC_TYPES___BSEARCHCOMPARE_T_H
+#define LLVM_LIBC_TYPES___BSEARCHCOMPARE_T_H
typedef int (*__bsearchcompare_t)(const void *, const void *);
-#endif // __LLVM_LIBC_TYPES_BSEARCHCOMPARE_T_H__
+#endif // LLVM_LIBC_TYPES___BSEARCHCOMPARE_T_H
diff --git a/include/llvm-libc-types/__call_once_func_t.h b/include/llvm-libc-types/__call_once_func_t.h
index bc8ed8331bd8..6d278da4f1d3 100644
--- a/include/llvm-libc-types/__call_once_func_t.h
+++ b/include/llvm-libc-types/__call_once_func_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CALL_ONCE_FUNC_T_H__
-#define __LLVM_LIBC_TYPES_CALL_ONCE_FUNC_T_H__
+#ifndef LLVM_LIBC_TYPES___CALL_ONCE_FUNC_T_H
+#define LLVM_LIBC_TYPES___CALL_ONCE_FUNC_T_H
typedef void (*__call_once_func_t)(void);
-#endif // __LLVM_LIBC_TYPES_CALL_ONCE_FUNC_T_H__
+#endif // LLVM_LIBC_TYPES___CALL_ONCE_FUNC_T_H
diff --git a/include/llvm-libc-types/__exec_argv_t.h b/include/llvm-libc-types/__exec_argv_t.h
index 35b687d9685d..4eff583768af 100644
--- a/include/llvm-libc-types/__exec_argv_t.h
+++ b/include/llvm-libc-types/__exec_argv_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_EXEC_ARGV_T_H__
-#define __LLVM_LIBC_TYPES_EXEC_ARGV_T_H__
+#ifndef LLVM_LIBC_TYPES___EXEC_ARGV_T_H
+#define LLVM_LIBC_TYPES___EXEC_ARGV_T_H
typedef char *const __exec_argv_t[];
-#endif // __LLVM_LIBC_TYPES_EXEC_ARGV_T_H__
+#endif // LLVM_LIBC_TYPES___EXEC_ARGV_T_H
diff --git a/include/llvm-libc-types/__exec_envp_t.h b/include/llvm-libc-types/__exec_envp_t.h
index 06eb2ddcb1fb..89e02754c4e4 100644
--- a/include/llvm-libc-types/__exec_envp_t.h
+++ b/include/llvm-libc-types/__exec_envp_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_EXEC_ENVP_T_H__
-#define __LLVM_LIBC_TYPES_EXEC_ENVP_T_H__
+#ifndef LLVM_LIBC_TYPES___EXEC_ENVP_T_H
+#define LLVM_LIBC_TYPES___EXEC_ENVP_T_H
typedef char *const __exec_envp_t[];
-#endif // __LLVM_LIBC_TYPES_EXEC_ENVP_T_H__
+#endif // LLVM_LIBC_TYPES___EXEC_ENVP_T_H
diff --git a/include/llvm-libc-types/__futex_word.h b/include/llvm-libc-types/__futex_word.h
index 85130ab4976b..04023c7e2d5f 100644
--- a/include/llvm-libc-types/__futex_word.h
+++ b/include/llvm-libc-types/__futex_word.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FUTEX_WORD_H__
-#define __LLVM_LIBC_TYPES_FUTEX_WORD_H__
+#ifndef LLVM_LIBC_TYPES___FUTEX_WORD_H
+#define LLVM_LIBC_TYPES___FUTEX_WORD_H
typedef struct {
// Futex word should be aligned appropriately to allow target atomic
@@ -17,4 +17,4 @@ typedef struct {
: _Alignof(__UINT32_TYPE__)) __UINT32_TYPE__ __word;
} __futex_word;
-#endif // __LLVM_LIBC_TYPES_FUTEX_WORD_H__
+#endif // LLVM_LIBC_TYPES___FUTEX_WORD_H
diff --git a/include/llvm-libc-types/__getoptargv_t.h b/include/llvm-libc-types/__getoptargv_t.h
index 81c67286c3a7..c26b9e9fa619 100644
--- a/include/llvm-libc-types/__getoptargv_t.h
+++ b/include/llvm-libc-types/__getoptargv_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_GETOPTARGV_T_H__
-#define __LLVM_LIBC_TYPES_GETOPTARGV_T_H__
+#ifndef LLVM_LIBC_TYPES___GETOPTARGV_T_H
+#define LLVM_LIBC_TYPES___GETOPTARGV_T_H
typedef char *const __getoptargv_t[];
-#endif // __LLVM_LIBC_TYPES_GETOPTARGV_T_H__
+#endif // LLVM_LIBC_TYPES___GETOPTARGV_T_H
diff --git a/include/llvm-libc-types/__mutex_type.h b/include/llvm-libc-types/__mutex_type.h
index a7ed8f843c3a..3779c78203ed 100644
--- a/include/llvm-libc-types/__mutex_type.h
+++ b/include/llvm-libc-types/__mutex_type.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES___MUTEX_T_H
-#define __LLVM_LIBC_TYPES___MUTEX_T_H
+#ifndef LLVM_LIBC_TYPES___MUTEX_TYPE_H
+#define LLVM_LIBC_TYPES___MUTEX_TYPE_H
-#include <llvm-libc-types/__futex_word.h>
+#include "llvm-libc-types/__futex_word.h"
typedef struct {
unsigned char __timed;
@@ -26,4 +26,4 @@ typedef struct {
#endif
} __mutex_type;
-#endif // __LLVM_LIBC_TYPES___MUTEX_T_H
+#endif // LLVM_LIBC_TYPES___MUTEX_TYPE_H
diff --git a/include/llvm-libc-types/__pthread_once_func_t.h b/include/llvm-libc-types/__pthread_once_func_t.h
index 5ace5cb7f151..7575029f08c2 100644
--- a/include/llvm-libc-types/__pthread_once_func_t.h
+++ b/include/llvm-libc-types/__pthread_once_func_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_ONCE_FUNC_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_ONCE_FUNC_T_H__
+#ifndef LLVM_LIBC_TYPES___PTHREAD_ONCE_FUNC_T_H
+#define LLVM_LIBC_TYPES___PTHREAD_ONCE_FUNC_T_H
typedef void (*__pthread_once_func_t)(void);
-#endif // __LLVM_LIBC_TYPES_PTHREAD_ONCE_FUNC_T_H__
+#endif // LLVM_LIBC_TYPES___PTHREAD_ONCE_FUNC_T_H
diff --git a/include/llvm-libc-types/__pthread_start_t.h b/include/llvm-libc-types/__pthread_start_t.h
index 1e05f9b49729..6b7ae40b1b77 100644
--- a/include/llvm-libc-types/__pthread_start_t.h
+++ b/include/llvm-libc-types/__pthread_start_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_START_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_START_T_H__
+#ifndef LLVM_LIBC_TYPES___PTHREAD_START_T_H
+#define LLVM_LIBC_TYPES___PTHREAD_START_T_H
typedef void *(*__pthread_start_t)(void *);
-#endif // __LLVM_LIBC_TYPES_PTHREAD_START_T_H__
+#endif // LLVM_LIBC_TYPES___PTHREAD_START_T_H
diff --git a/include/llvm-libc-types/__pthread_tss_dtor_t.h b/include/llvm-libc-types/__pthread_tss_dtor_t.h
index 1b54d31a7977..c67b6045936d 100644
--- a/include/llvm-libc-types/__pthread_tss_dtor_t.h
+++ b/include/llvm-libc-types/__pthread_tss_dtor_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_TSS_DTOR_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_TSS_DTOR_T_H__
+#ifndef LLVM_LIBC_TYPES___PTHREAD_TSS_DTOR_T_H
+#define LLVM_LIBC_TYPES___PTHREAD_TSS_DTOR_T_H
typedef void (*__pthread_tss_dtor_t)(void *);
-#endif // __LLVM_LIBC_TYPES_PTHREAD_TSS_DTOR_T_H__
+#endif // LLVM_LIBC_TYPES___PTHREAD_TSS_DTOR_T_H
diff --git a/include/llvm-libc-types/__qsortcompare_t.h b/include/llvm-libc-types/__qsortcompare_t.h
index 82bd4cc1fcd0..48fc9ccb4409 100644
--- a/include/llvm-libc-types/__qsortcompare_t.h
+++ b/include/llvm-libc-types/__qsortcompare_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_QSORTCOMPARE_T_H__
-#define __LLVM_LIBC_TYPES_QSORTCOMPARE_T_H__
+#ifndef LLVM_LIBC_TYPES___QSORTCOMPARE_T_H
+#define LLVM_LIBC_TYPES___QSORTCOMPARE_T_H
typedef int (*__qsortcompare_t)(const void *, const void *);
-#endif // __LLVM_LIBC_TYPES_QSORTCOMPARE_T_H__
+#endif // LLVM_LIBC_TYPES___QSORTCOMPARE_T_H
diff --git a/include/llvm-libc-types/__qsortrcompare_t.h b/include/llvm-libc-types/__qsortrcompare_t.h
index febf79d9f90b..f6b058864359 100644
--- a/include/llvm-libc-types/__qsortrcompare_t.h
+++ b/include/llvm-libc-types/__qsortrcompare_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_QSORTRCOMPARE_T_H__
-#define __LLVM_LIBC_TYPES_QSORTRCOMPARE_T_H__
+#ifndef LLVM_LIBC_TYPES___QSORTRCOMPARE_T_H
+#define LLVM_LIBC_TYPES___QSORTRCOMPARE_T_H
typedef int (*__qsortrcompare_t)(const void *, const void *, void *);
-#endif // __LLVM_LIBC_TYPES_QSORTRCOMPARE_T_H__
+#endif // LLVM_LIBC_TYPES___QSORTRCOMPARE_T_H
diff --git a/include/llvm-libc-types/__sighandler_t.h b/include/llvm-libc-types/__sighandler_t.h
index bd0ad98d8529..9c1ac997fc4e 100644
--- a/include/llvm-libc-types/__sighandler_t.h
+++ b/include/llvm-libc-types/__sighandler_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIGHANDLER_T_H__
-#define __LLVM_LIBC_TYPES_SIGHANDLER_T_H__
+#ifndef LLVM_LIBC_TYPES___SIGHANDLER_T_H
+#define LLVM_LIBC_TYPES___SIGHANDLER_T_H
typedef void (*__sighandler_t)(int);
-#endif // __LLVM_LIBC_TYPES_SIGHANDLER_T_H__
+#endif // LLVM_LIBC_TYPES___SIGHANDLER_T_H
diff --git a/include/llvm-libc-types/__thread_type.h b/include/llvm-libc-types/__thread_type.h
index da5b898e5750..645573f544a9 100644
--- a/include/llvm-libc-types/__thread_type.h
+++ b/include/llvm-libc-types/__thread_type.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_THREAD_TYPE_H__
-#define __LLVM_LIBC_TYPES_THREAD_TYPE_H__
+#ifndef LLVM_LIBC_TYPES___THREAD_TYPE_H
+#define LLVM_LIBC_TYPES___THREAD_TYPE_H
typedef struct {
void *__attrib;
} __thread_type;
-#endif // __LLVM_LIBC_TYPES_THREAD_TYPE_H__
+#endif // LLVM_LIBC_TYPES___THREAD_TYPE_H
diff --git a/include/llvm-libc-types/blkcnt_t.h b/include/llvm-libc-types/blkcnt_t.h
index acd8d3467ec5..9dea8f033d6d 100644
--- a/include/llvm-libc-types/blkcnt_t.h
+++ b/include/llvm-libc-types/blkcnt_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_BLKCNT_T_H__
-#define __LLVM_LIBC_TYPES_BLKCNT_T_H__
+#ifndef LLVM_LIBC_TYPES_BLKCNT_T_H
+#define LLVM_LIBC_TYPES_BLKCNT_T_H
typedef __INTPTR_TYPE__ blkcnt_t;
-#endif // __LLVM_LIBC_TYPES_BLKCNT_T_H__
+#endif // LLVM_LIBC_TYPES_BLKCNT_T_H
diff --git a/include/llvm-libc-types/blksize_t.h b/include/llvm-libc-types/blksize_t.h
index 99ddac56194a..7caa9705cca3 100644
--- a/include/llvm-libc-types/blksize_t.h
+++ b/include/llvm-libc-types/blksize_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_BLKSIZE_T_H__
-#define __LLVM_LIBC_TYPES_BLKSIZE_T_H__
+#ifndef LLVM_LIBC_TYPES_BLKSIZE_T_H
+#define LLVM_LIBC_TYPES_BLKSIZE_T_H
typedef __INTPTR_TYPE__ blksize_t;
-#endif // __LLVM_LIBC_TYPES_BLKSIZE_T_H__
+#endif // LLVM_LIBC_TYPES_BLKSIZE_T_H
diff --git a/include/llvm-libc-types/cc_t.h b/include/llvm-libc-types/cc_t.h
index e08523cc3ec9..40d99ad22da2 100644
--- a/include/llvm-libc-types/cc_t.h
+++ b/include/llvm-libc-types/cc_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CC_T_H__
-#define __LLVM_LIBC_TYPES_CC_T_H__
+#ifndef LLVM_LIBC_TYPES_CC_T_H
+#define LLVM_LIBC_TYPES_CC_T_H
typedef unsigned char cc_t;
-#endif // __LLVM_LIBC_TYPES_CC_T_H__
+#endif // LLVM_LIBC_TYPES_CC_T_H
diff --git a/include/llvm-libc-types/clock_t.h b/include/llvm-libc-types/clock_t.h
index b7969d602c6b..8759ee999fb5 100644
--- a/include/llvm-libc-types/clock_t.h
+++ b/include/llvm-libc-types/clock_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CLOCK_T_H__
-#define __LLVM_LIBC_TYPES_CLOCK_T_H__
+#ifndef LLVM_LIBC_TYPES_CLOCK_T_H
+#define LLVM_LIBC_TYPES_CLOCK_T_H
typedef long clock_t;
-#endif // __LLVM_LIBC_TYPES_CLOCK_T_H__
+#endif // LLVM_LIBC_TYPES_CLOCK_T_H
diff --git a/include/llvm-libc-types/clockid_t.h b/include/llvm-libc-types/clockid_t.h
index ddaceb664ec1..4b059599502c 100644
--- a/include/llvm-libc-types/clockid_t.h
+++ b/include/llvm-libc-types/clockid_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CLOCKID_T_H__
-#define __LLVM_LIBC_TYPES_CLOCKID_T_H__
+#ifndef LLVM_LIBC_TYPES_CLOCKID_T_H
+#define LLVM_LIBC_TYPES_CLOCKID_T_H
typedef int clockid_t;
-#endif // __LLVM_LIBC_TYPES_CLOCKID_T_H__
+#endif // LLVM_LIBC_TYPES_CLOCKID_T_H
diff --git a/include/llvm-libc-types/cnd_t.h b/include/llvm-libc-types/cnd_t.h
index 09a29ac43dee..1159ac435792 100644
--- a/include/llvm-libc-types/cnd_t.h
+++ b/include/llvm-libc-types/cnd_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CND_T_H__
-#define __LLVM_LIBC_TYPES_CND_T_H__
+#ifndef LLVM_LIBC_TYPES_CND_T_H
+#define LLVM_LIBC_TYPES_CND_T_H
#include "mtx_t.h"
@@ -17,4 +17,4 @@ typedef struct {
mtx_t __qmtx;
} cnd_t;
-#endif // __LLVM_LIBC_TYPES_CND_T_H__
+#endif // LLVM_LIBC_TYPES_CND_T_H
diff --git a/include/llvm-libc-types/cookie_io_functions_t.h b/include/llvm-libc-types/cookie_io_functions_t.h
index df904162a897..a3e7c32a5096 100644
--- a/include/llvm-libc-types/cookie_io_functions_t.h
+++ b/include/llvm-libc-types/cookie_io_functions_t.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
-#define __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
+#ifndef LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
+#define LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
-#include <llvm-libc-types/off64_t.h>
-#include <llvm-libc-types/size_t.h>
-#include <llvm-libc-types/ssize_t.h>
+#include "llvm-libc-types/off64_t.h"
+#include "llvm-libc-types/size_t.h"
+#include "llvm-libc-types/ssize_t.h"
typedef ssize_t cookie_read_function_t(void *, char *, size_t);
typedef ssize_t cookie_write_function_t(void *, const char *, size_t);
@@ -25,4 +25,4 @@ typedef struct {
cookie_close_function_t *close;
} cookie_io_functions_t;
-#endif // __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
+#endif // LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
diff --git a/include/llvm-libc-types/cpu_set_t.h b/include/llvm-libc-types/cpu_set_t.h
index 79f694aeda60..e7f52597e147 100644
--- a/include/llvm-libc-types/cpu_set_t.h
+++ b/include/llvm-libc-types/cpu_set_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_CPU_SET_T_H
-#define __LLVM_LIBC_TYPES_CPU_SET_T_H
+#ifndef LLVM_LIBC_TYPES_CPU_SET_T_H
+#define LLVM_LIBC_TYPES_CPU_SET_T_H
typedef struct {
// If a processor with more than 1024 CPUs is to be supported in future,
@@ -15,4 +15,4 @@ typedef struct {
unsigned long __mask[128 / sizeof(unsigned long)];
} cpu_set_t;
-#endif // __LLVM_LIBC_TYPES_CPU_SET_T_H
+#endif // LLVM_LIBC_TYPES_CPU_SET_T_H
diff --git a/include/llvm-libc-types/dev_t.h b/include/llvm-libc-types/dev_t.h
index 9fbc41a49b89..3181e3415f2e 100644
--- a/include/llvm-libc-types/dev_t.h
+++ b/include/llvm-libc-types/dev_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_DEV_T_H__
-#define __LLVM_LIBC_TYPES_DEV_T_H__
+#ifndef LLVM_LIBC_TYPES_DEV_T_H
+#define LLVM_LIBC_TYPES_DEV_T_H
typedef __UINT64_TYPE__ dev_t;
-#endif // __LLVM_LIBC_TYPES_DEV_T_H__
+#endif // LLVM_LIBC_TYPES_DEV_T_H
diff --git a/include/llvm-libc-types/div_t.h b/include/llvm-libc-types/div_t.h
index e495a1c3f9dc..450603d69f35 100644
--- a/include/llvm-libc-types/div_t.h
+++ b/include/llvm-libc-types/div_t.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_DIV_T_H__
-#define __LLVM_LIBC_TYPES_DIV_T_H__
+#ifndef LLVM_LIBC_TYPES_DIV_T_H
+#define LLVM_LIBC_TYPES_DIV_T_H
typedef struct {
int quot;
int rem;
} div_t;
-#endif // __LLVM_LIBC_TYPES_DIV_T_H__
+#endif // LLVM_LIBC_TYPES_DIV_T_H
diff --git a/include/llvm-libc-types/double_t.h b/include/llvm-libc-types/double_t.h
index 2aa471de4840..c4ad08afddfa 100644
--- a/include/llvm-libc-types/double_t.h
+++ b/include/llvm-libc-types/double_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_DOUBLE_T_H__
-#define __LLVM_LIBC_TYPES_DOUBLE_T_H__
+#ifndef LLVM_LIBC_TYPES_DOUBLE_T_H
+#define LLVM_LIBC_TYPES_DOUBLE_T_H
#if !defined(__FLT_EVAL_METHOD__) || __FLT_EVAL_METHOD__ == 0
#define __LLVM_LIBC_DOUBLE_T double
@@ -21,4 +21,4 @@
typedef __LLVM_LIBC_DOUBLE_T double_t;
-#endif // __LLVM_LIBC_TYPES_DOUBLE_T_H__
+#endif // LLVM_LIBC_TYPES_DOUBLE_T_H
diff --git a/include/llvm-libc-types/fd_set.h b/include/llvm-libc-types/fd_set.h
index 54e3fc654c06..fd1bde24c90e 100644
--- a/include/llvm-libc-types/fd_set.h
+++ b/include/llvm-libc-types/fd_set.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FD_SET_H__
-#define __LLVM_LIBC_TYPES_FD_SET_H__
+#ifndef LLVM_LIBC_TYPES_FD_SET_H
+#define LLVM_LIBC_TYPES_FD_SET_H
-#include <llvm-libc-macros/sys-select-macros.h> // FD_SETSIZE
+#include "llvm-libc-macros/sys-select-macros.h" // FD_SETSIZE
typedef struct {
__FD_SET_WORD_TYPE __set[__FD_SET_ARRAYSIZE];
} fd_set;
-#endif // __LLVM_LIBC_TYPES_FD_SET_H__
+#endif // LLVM_LIBC_TYPES_FD_SET_H
diff --git a/include/llvm-libc-types/fenv_t.h b/include/llvm-libc-types/fenv_t.h
index 86fcf2e49a7f..c83f23894c0c 100644
--- a/include/llvm-libc-types/fenv_t.h
+++ b/include/llvm-libc-types/fenv_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FENV_T_H__
-#define __LLVM_LIBC_TYPES_FENV_T_H__
+#ifndef LLVM_LIBC_TYPES_FENV_T_H
+#define LLVM_LIBC_TYPES_FENV_T_H
#ifdef __aarch64__
typedef struct {
@@ -33,4 +33,4 @@ typedef struct {
#error "fenv_t not defined for your platform"
#endif
-#endif // __LLVM_LIBC_TYPES_FENV_T_H__
+#endif // LLVM_LIBC_TYPES_FENV_T_H
diff --git a/include/llvm-libc-types/fexcept_t.h b/include/llvm-libc-types/fexcept_t.h
index 6e7969c1be0a..60687bd1318a 100644
--- a/include/llvm-libc-types/fexcept_t.h
+++ b/include/llvm-libc-types/fexcept_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FEXCEPT_T_H__
-#define __LLVM_LIBC_TYPES_FEXCEPT_T_H__
+#ifndef LLVM_LIBC_TYPES_FEXCEPT_T_H
+#define LLVM_LIBC_TYPES_FEXCEPT_T_H
typedef int fexcept_t;
-#endif // __LLVM_LIBC_TYPES_FEXCEPT_T_H__
+#endif // LLVM_LIBC_TYPES_FEXCEPT_T_H
diff --git a/include/llvm-libc-types/float128.h b/include/llvm-libc-types/float128.h
new file mode 100644
index 000000000000..82ebb79f1f58
--- /dev/null
+++ b/include/llvm-libc-types/float128.h
@@ -0,0 +1,36 @@
+//===-- Definition of float128 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_FLOAT128_H
+#define LLVM_LIBC_TYPES_FLOAT128_H
+
+#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
+
+// Currently, C23 `_Float128` type is only defined as a built-in type in GCC 7
+// or later, and only for C. For C++, or for clang, `__float128` is defined
+// instead, and only on x86-64 targets.
+//
+// TODO: Update C23 `_Float128` type detection again when clang supports it.
+// https://github.com/llvm/llvm-project/issues/80195
+#if defined(__STDC_IEC_60559_BFP__) && !defined(__clang__) && \
+ !defined(__cplusplus)
+#define LIBC_TYPES_HAS_FLOAT128
+typedef _Float128 float128;
+#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
+// Use __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__ to
+// notify the availability of __float128.
+// clang also uses __FLOAT128__ macro to notify the availability of __float128
+// type: https://reviews.llvm.org/D15120
+#define LIBC_TYPES_HAS_FLOAT128
+typedef __float128 float128;
+#elif (LDBL_MANT_DIG == 113)
+#define LIBC_TYPES_HAS_FLOAT128
+typedef long double float128;
+#endif
+
+#endif // LLVM_LIBC_TYPES_FLOAT128_H
diff --git a/include/llvm-libc-types/float_t.h b/include/llvm-libc-types/float_t.h
index 8df3bf05f6a1..5027249c30d3 100644
--- a/include/llvm-libc-types/float_t.h
+++ b/include/llvm-libc-types/float_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_FLOAT_T_H__
-#define __LLVM_LIBC_TYPES_FLOAT_T_H__
+#ifndef LLVM_LIBC_TYPES_FLOAT_T_H
+#define LLVM_LIBC_TYPES_FLOAT_T_H
#if !defined(__FLT_EVAL_METHOD__) || __FLT_EVAL_METHOD__ == 0
#define __LLVM_LIBC_FLOAT_T float
@@ -21,4 +21,4 @@
typedef __LLVM_LIBC_FLOAT_T float_t;
-#endif // __LLVM_LIBC_TYPES_FLOAT_T_H__
+#endif // LLVM_LIBC_TYPES_FLOAT_T_H
diff --git a/include/llvm-libc-types/fsblkcnt_t.h b/include/llvm-libc-types/fsblkcnt_t.h
new file mode 100644
index 000000000000..88a53d38cb1b
--- /dev/null
+++ b/include/llvm-libc-types/fsblkcnt_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of fsblkcnt_t 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_FSBLKCNT_T_H
+#define LLVM_LIBC_TYPES_FSBLKCNT_T_H
+
+typedef __SIZE_TYPE__ fsblkcnt_t;
+
+#endif // LLVM_LIBC_TYPES_FSBLKCNT_T_H
diff --git a/include/llvm-libc-types/fsfilcnt_t.h b/include/llvm-libc-types/fsfilcnt_t.h
new file mode 100644
index 000000000000..c5693591907a
--- /dev/null
+++ b/include/llvm-libc-types/fsfilcnt_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of fsfilcnt_t 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_FSFILCNT_T_H
+#define LLVM_LIBC_TYPES_FSFILCNT_T_H
+
+typedef __SIZE_TYPE__ fsfilcnt_t;
+
+#endif // LLVM_LIBC_TYPES_FSFILCNT_T_H
diff --git a/include/llvm-libc-types/gid_t.h b/include/llvm-libc-types/gid_t.h
index 664aee020a4e..cfe36ce9906b 100644
--- a/include/llvm-libc-types/gid_t.h
+++ b/include/llvm-libc-types/gid_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_GID_T_H__
-#define __LLVM_LIBC_TYPES_GID_T_H__
+#ifndef LLVM_LIBC_TYPES_GID_T_H
+#define LLVM_LIBC_TYPES_GID_T_H
typedef __UINT32_TYPE__ gid_t;
-#endif // __LLVM_LIBC_TYPES_GID_T_H__
+#endif // LLVM_LIBC_TYPES_GID_T_H
diff --git a/include/llvm-libc-types/ino_t.h b/include/llvm-libc-types/ino_t.h
index 0f5abd96c2b7..148bd67f98fe 100644
--- a/include/llvm-libc-types/ino_t.h
+++ b/include/llvm-libc-types/ino_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_INO_T_H__
-#define __LLVM_LIBC_TYPES_INO_T_H__
+#ifndef LLVM_LIBC_TYPES_INO_T_H
+#define LLVM_LIBC_TYPES_INO_T_H
typedef __UINTPTR_TYPE__ ino_t;
-#endif // __LLVM_LIBC_TYPES_INO_T_H__
+#endif // LLVM_LIBC_TYPES_INO_T_H
diff --git a/include/llvm-libc-types/jmp_buf.h b/include/llvm-libc-types/jmp_buf.h
index 6af4e8ebad92..29a1df9ad682 100644
--- a/include/llvm-libc-types/jmp_buf.h
+++ b/include/llvm-libc-types/jmp_buf.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_JMP_BUF_H__
-#define __LLVM_LIBC_TYPES_JMP_BUF_H__
+#ifndef LLVM_LIBC_TYPES_JMP_BUF_H
+#define LLVM_LIBC_TYPES_JMP_BUF_H
typedef struct {
#ifdef __x86_64__
@@ -39,4 +39,4 @@ typedef struct {
typedef __jmp_buf jmp_buf[1];
-#endif // __LLVM_LIBC_TYPES_JMP_BUF_H__
+#endif // LLVM_LIBC_TYPES_JMP_BUF_H
diff --git a/include/llvm-libc-types/ldiv_t.h b/include/llvm-libc-types/ldiv_t.h
index 9bd8d253330a..5c64ec10d918 100644
--- a/include/llvm-libc-types/ldiv_t.h
+++ b/include/llvm-libc-types/ldiv_t.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_LDIV_T_H__
-#define __LLVM_LIBC_TYPES_LDIV_T_H__
+#ifndef LLVM_LIBC_TYPES_LDIV_T_H
+#define LLVM_LIBC_TYPES_LDIV_T_H
typedef struct {
long quot;
long rem;
} ldiv_t;
-#endif // __LLVM_LIBC_TYPES_LDIV_T_H__
+#endif // LLVM_LIBC_TYPES_LDIV_T_H
diff --git a/include/llvm-libc-types/lldiv_t.h b/include/llvm-libc-types/lldiv_t.h
index 109304d12078..5b8dcbef9470 100644
--- a/include/llvm-libc-types/lldiv_t.h
+++ b/include/llvm-libc-types/lldiv_t.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_LLDIV_T_H__
-#define __LLVM_LIBC_TYPES_LLDIV_T_H__
+#ifndef LLVM_LIBC_TYPES_LLDIV_T_H
+#define LLVM_LIBC_TYPES_LLDIV_T_H
typedef struct {
long long quot;
long long rem;
} lldiv_t;
-#endif // __LLVM_LIBC_TYPES_LLDIV_T_H__
+#endif // LLVM_LIBC_TYPES_LLDIV_T_H
diff --git a/include/llvm-libc-types/mbstate_t.h b/include/llvm-libc-types/mbstate_t.h
new file mode 100644
index 000000000000..540d50975a26
--- /dev/null
+++ b/include/llvm-libc-types/mbstate_t.h
@@ -0,0 +1,16 @@
+//===-- Definition of mbstate_t 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_MBSTATE_T_H
+#define LLVM_LIBC_TYPES_MBSTATE_T_H
+
+// TODO: Complete this once we implement functions that operate on this type.
+typedef struct {
+} mbstate_t;
+
+#endif // LLVM_LIBC_TYPES_MBSTATE_T_H
diff --git a/include/llvm-libc-types/mode_t.h b/include/llvm-libc-types/mode_t.h
index 20037bb9ac8f..fe09060d9a6e 100644
--- a/include/llvm-libc-types/mode_t.h
+++ b/include/llvm-libc-types/mode_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_MODE_T_H
-#define __LLVM_LIBC_TYPES_MODE_T_H
+#ifndef LLVM_LIBC_TYPES_MODE_T_H
+#define LLVM_LIBC_TYPES_MODE_T_H
typedef unsigned mode_t;
-#endif // __LLVM_LIBC_TYPES_MODE_T_H
+#endif // LLVM_LIBC_TYPES_MODE_T_H
diff --git a/include/llvm-libc-types/mtx_t.h b/include/llvm-libc-types/mtx_t.h
index ac6453eeabf0..ebf79871c935 100644
--- a/include/llvm-libc-types/mtx_t.h
+++ b/include/llvm-libc-types/mtx_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_MTX_T_H__
-#define __LLVM_LIBC_TYPES_MTX_T_H__
+#ifndef LLVM_LIBC_TYPES_MTX_T_H
+#define LLVM_LIBC_TYPES_MTX_T_H
-#include <llvm-libc-types/__mutex_type.h>
+#include "llvm-libc-types/__mutex_type.h"
typedef __mutex_type mtx_t;
-#endif // __LLVM_LIBC_TYPES_MTX_T_H__
+#endif // LLVM_LIBC_TYPES_MTX_T_H
diff --git a/include/llvm-libc-types/nlink_t.h b/include/llvm-libc-types/nlink_t.h
index 1826144b3c88..7e0016a9af95 100644
--- a/include/llvm-libc-types/nlink_t.h
+++ b/include/llvm-libc-types/nlink_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_NLINK_T_H__
-#define __LLVM_LIBC_TYPES_NLINK_T_H__
+#ifndef LLVM_LIBC_TYPES_NLINK_T_H
+#define LLVM_LIBC_TYPES_NLINK_T_H
typedef __UINTPTR_TYPE__ nlink_t;
-#endif // __LLVM_LIBC_TYPES_NLINK_T_H__
+#endif // LLVM_LIBC_TYPES_NLINK_T_H
diff --git a/include/llvm-libc-types/off64_t.h b/include/llvm-libc-types/off64_t.h
index 0f95caa19cca..669698a8c05f 100644
--- a/include/llvm-libc-types/off64_t.h
+++ b/include/llvm-libc-types/off64_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_OFF64_T_H__
-#define __LLVM_LIBC_TYPES_OFF64_T_H__
+#ifndef LLVM_LIBC_TYPES_OFF64_T_H
+#define LLVM_LIBC_TYPES_OFF64_T_H
typedef __INT64_TYPE__ off64_t;
-#endif // __LLVM_LIBC_TYPES_OFF64_T_H__
+#endif // LLVM_LIBC_TYPES_OFF64_T_H
diff --git a/include/llvm-libc-types/off_t.h b/include/llvm-libc-types/off_t.h
index 111b29aa68d8..63224b6831d5 100644
--- a/include/llvm-libc-types/off_t.h
+++ b/include/llvm-libc-types/off_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_OFF_T_H__
-#define __LLVM_LIBC_TYPES_OFF_T_H__
+#ifndef LLVM_LIBC_TYPES_OFF_T_H
+#define LLVM_LIBC_TYPES_OFF_T_H
typedef __INT64_TYPE__ off_t;
-#endif // __LLVM_LIBC_TYPES_OFF_T_H__
+#endif // LLVM_LIBC_TYPES_OFF_T_H
diff --git a/include/llvm-libc-types/once_flag.h b/include/llvm-libc-types/once_flag.h
index 77bab28338a0..f80d35e317e9 100644
--- a/include/llvm-libc-types/once_flag.h
+++ b/include/llvm-libc-types/once_flag.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_ONCE_FLAG_H__
-#define __LLVM_LIBC_TYPES_ONCE_FLAG_H__
+#ifndef LLVM_LIBC_TYPES_ONCE_FLAG_H
+#define LLVM_LIBC_TYPES_ONCE_FLAG_H
-#include <llvm-libc-types/__futex_word.h>
+#include "llvm-libc-types/__futex_word.h"
#ifdef __linux__
typedef __futex_word once_flag;
@@ -17,4 +17,4 @@ typedef __futex_word once_flag;
#error "Once flag type not defined for the target platform."
#endif
-#endif // __LLVM_LIBC_TYPES_ONCE_FLAG_H__
+#endif // LLVM_LIBC_TYPES_ONCE_FLAG_H
diff --git a/include/llvm-libc-types/pid_t.h b/include/llvm-libc-types/pid_t.h
index d78fde74f34a..0397bd249032 100644
--- a/include/llvm-libc-types/pid_t.h
+++ b/include/llvm-libc-types/pid_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PID_t_H__
-#define __LLVM_LIBC_TYPES_PID_t_H__
+#ifndef LLVM_LIBC_TYPES_PID_T_H
+#define LLVM_LIBC_TYPES_PID_T_H
typedef __INT32_TYPE__ pid_t;
-#endif // __LLVM_LIBC_TYPES_PID_t_H__
+#endif // LLVM_LIBC_TYPES_PID_T_H
diff --git a/include/llvm-libc-types/posix_spawn_file_actions_t.h b/include/llvm-libc-types/posix_spawn_file_actions_t.h
index 55adbd198de8..3062da3a54b5 100644
--- a/include/llvm-libc-types/posix_spawn_file_actions_t.h
+++ b/include/llvm-libc-types/posix_spawn_file_actions_t.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H
-#define __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H
+#ifndef LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_H
+#define LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_H
typedef struct {
void *__front;
void *__back;
} posix_spawn_file_actions_t;
-#endif // __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H
+#endif // LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_H
diff --git a/include/llvm-libc-types/posix_spawnattr_t.h b/include/llvm-libc-types/posix_spawnattr_t.h
index f1bcb3e1434f..47cadc7cdda1 100644
--- a/include/llvm-libc-types/posix_spawnattr_t.h
+++ b/include/llvm-libc-types/posix_spawnattr_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
-#define __LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
+#ifndef LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
+#define LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
typedef struct {
// This data structure will be populated as required.
} posix_spawnattr_t;
-#endif // __LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
+#endif // LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H
diff --git a/include/llvm-libc-types/pthread_attr_t.h b/include/llvm-libc-types/pthread_attr_t.h
index 7bf8a5402f28..7512193ef97b 100644
--- a/include/llvm-libc-types/pthread_attr_t.h
+++ b/include/llvm-libc-types/pthread_attr_t.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
-#define __LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
+#ifndef LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
-#include <llvm-libc-types/size_t.h>
+#include "llvm-libc-types/size_t.h"
typedef struct {
int __detachstate;
@@ -18,4 +18,4 @@ typedef struct {
size_t __guardsize;
} pthread_attr_t;
-#endif // __LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
+#endif // LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
diff --git a/include/llvm-libc-types/pthread_key_t.h b/include/llvm-libc-types/pthread_key_t.h
index 351e37614a01..e73c7e26c17c 100644
--- a/include/llvm-libc-types/pthread_key_t.h
+++ b/include/llvm-libc-types/pthread_key_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_KEY_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_KEY_T_H__
+#ifndef LLVM_LIBC_TYPES_PTHREAD_KEY_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_KEY_T_H
typedef unsigned int pthread_key_t;
-#endif // __LLVM_LIBC_TYPES_PTHREAD_KEY_T_H__
+#endif // LLVM_LIBC_TYPES_PTHREAD_KEY_T_H
diff --git a/include/llvm-libc-types/pthread_mutex_t.h b/include/llvm-libc-types/pthread_mutex_t.h
index 65e43538cd27..cf2194d719f3 100644
--- a/include/llvm-libc-types/pthread_mutex_t.h
+++ b/include/llvm-libc-types/pthread_mutex_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
-#define __LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
+#ifndef LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
-#include <llvm-libc-types/__mutex_type.h>
+#include "llvm-libc-types/__mutex_type.h"
typedef __mutex_type pthread_mutex_t;
-#endif // __LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
+#endif // LLVM_LIBC_TYPES_PTHREAD_MUTEX_T_H
diff --git a/include/llvm-libc-types/pthread_mutexattr_t.h b/include/llvm-libc-types/pthread_mutexattr_t.h
index be1ff5611ed4..8f159a61420c 100644
--- a/include/llvm-libc-types/pthread_mutexattr_t.h
+++ b/include/llvm-libc-types/pthread_mutexattr_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
-#define __LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
+#ifndef LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
// pthread_mutexattr_t is a collection bit mapped flags. The mapping is internal
// detail of the libc implementation.
typedef unsigned int pthread_mutexattr_t;
-#endif // __LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
+#endif // LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H
diff --git a/include/llvm-libc-types/pthread_once_t.h b/include/llvm-libc-types/pthread_once_t.h
index 6d65f8f74052..8ea926f4ee7d 100644
--- a/include/llvm-libc-types/pthread_once_t.h
+++ b/include/llvm-libc-types/pthread_once_t.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H__
+#ifndef LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H
-#include <llvm-libc-types/__futex_word.h>
+#include "llvm-libc-types/__futex_word.h"
#ifdef __linux__
typedef __futex_word pthread_once_t;
@@ -17,4 +17,4 @@ typedef __futex_word pthread_once_t;
#error "Once flag type not defined for the target platform."
#endif
-#endif // __LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H__
+#endif // LLVM_LIBC_TYPES_PTHREAD_ONCE_T_H
diff --git a/include/llvm-libc-types/pthread_t.h b/include/llvm-libc-types/pthread_t.h
index 8130491274ef..63cc0d7dd74c 100644
--- a/include/llvm-libc-types/pthread_t.h
+++ b/include/llvm-libc-types/pthread_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_PTHREAD_T_H__
-#define __LLVM_LIBC_TYPES_PTHREAD_T_H__
+#ifndef LLVM_LIBC_TYPES_PTHREAD_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_T_H
-#include <llvm-libc-types/__thread_type.h>
+#include "llvm-libc-types/__thread_type.h"
typedef __thread_type pthread_t;
-#endif // __LLVM_LIBC_TYPES_PTHREAD_T_H__
+#endif // LLVM_LIBC_TYPES_PTHREAD_T_H
diff --git a/include/llvm-libc-types/rlim_t.h b/include/llvm-libc-types/rlim_t.h
index 4e5acfb24c1b..016ec7bdc5b1 100644
--- a/include/llvm-libc-types/rlim_t.h
+++ b/include/llvm-libc-types/rlim_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_RLIM_T_H__
-#define __LLVM_LIBC_TYPES_RLIM_T_H__
+#ifndef LLVM_LIBC_TYPES_RLIM_T_H
+#define LLVM_LIBC_TYPES_RLIM_T_H
typedef __UINT64_TYPE__ rlim_t;
-#endif // __LLVM_LIBC_TYPES_RLIM_T_H__
+#endif // LLVM_LIBC_TYPES_RLIM_T_H
diff --git a/include/llvm-libc-types/rpc_opcodes_t.h b/include/llvm-libc-types/rpc_opcodes_t.h
index 7b85428dd344..faed7b5f5ff4 100644
--- a/include/llvm-libc-types/rpc_opcodes_t.h
+++ b/include/llvm-libc-types/rpc_opcodes_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_RPC_OPCODE_H__
-#define __LLVM_LIBC_TYPES_RPC_OPCODE_H__
+#ifndef LLVM_LIBC_TYPES_RPC_OPCODES_T_H
+#define LLVM_LIBC_TYPES_RPC_OPCODES_T_H
typedef enum {
RPC_NOOP = 0,
@@ -31,7 +31,10 @@ typedef enum {
RPC_FTELL,
RPC_FFLUSH,
RPC_UNGETC,
+ RPC_PRINTF_TO_STDOUT,
+ RPC_PRINTF_TO_STDERR,
+ RPC_PRINTF_TO_STREAM,
RPC_LAST = 0xFFFF,
} rpc_opcode_t;
-#endif // __LLVM_LIBC_TYPES_RPC_OPCODE_H__
+#endif // LLVM_LIBC_TYPES_RPC_OPCODES_T_H
diff --git a/include/llvm-libc-types/sa_family_t.h b/include/llvm-libc-types/sa_family_t.h
index 52b69957b0d3..0a010b678ddb 100644
--- a/include/llvm-libc-types/sa_family_t.h
+++ b/include/llvm-libc-types/sa_family_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SA_FAMILY_T_H__
-#define __LLVM_LIBC_TYPES_SA_FAMILY_T_H__
+#ifndef LLVM_LIBC_TYPES_SA_FAMILY_T_H
+#define LLVM_LIBC_TYPES_SA_FAMILY_T_H
// The posix standard only says of sa_family_t that it must be unsigned. The
// linux man page for "address_families" lists approximately 32 different
@@ -16,4 +16,4 @@
typedef unsigned short sa_family_t;
-#endif // __LLVM_LIBC_TYPES_SA_FAMILY_T_H__
+#endif // LLVM_LIBC_TYPES_SA_FAMILY_T_H
diff --git a/include/llvm-libc-types/sig_atomic_t.h b/include/llvm-libc-types/sig_atomic_t.h
index 324629c1b55c..2ef375806791 100644
--- a/include/llvm-libc-types/sig_atomic_t.h
+++ b/include/llvm-libc-types/sig_atomic_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIG_ATOMIC_T_H__
-#define __LLVM_LIBC_TYPES_SIG_ATOMIC_T_H__
+#ifndef LLVM_LIBC_TYPES_SIG_ATOMIC_T_H
+#define LLVM_LIBC_TYPES_SIG_ATOMIC_T_H
typedef int sig_atomic_t;
-#endif // __LLVM_LIBC_TYPES_SIG_ATOMIC_T_H__
+#endif // LLVM_LIBC_TYPES_SIG_ATOMIC_T_H
diff --git a/include/llvm-libc-types/siginfo_t.h b/include/llvm-libc-types/siginfo_t.h
index ef8af78a88be..dafe9c1b5f8e 100644
--- a/include/llvm-libc-types/siginfo_t.h
+++ b/include/llvm-libc-types/siginfo_t.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIGINFO_T_H__
-#define __LLVM_LIBC_TYPES_SIGINFO_T_H__
+#ifndef LLVM_LIBC_TYPES_SIGINFO_T_H
+#define LLVM_LIBC_TYPES_SIGINFO_T_H
-#include <llvm-libc-types/clock_t.h>
-#include <llvm-libc-types/pid_t.h>
-#include <llvm-libc-types/uid_t.h>
-#include <llvm-libc-types/union_sigval.h>
+#include "llvm-libc-types/clock_t.h"
+#include "llvm-libc-types/pid_t.h"
+#include "llvm-libc-types/uid_t.h"
+#include "llvm-libc-types/union_sigval.h"
#define SI_MAX_SIZE 128
@@ -106,4 +106,4 @@ typedef struct {
#define si_syscall _sifields._sigsys._syscall
#define si_arch _sifields._sigsys._arch
-#endif // __LLVM_LIBC_TYPES_SIGINFO_T_H__
+#endif // LLVM_LIBC_TYPES_SIGINFO_T_H
diff --git a/include/llvm-libc-types/sigset_t.h b/include/llvm-libc-types/sigset_t.h
index bcfbc29996ae..311a92b823ff 100644
--- a/include/llvm-libc-types/sigset_t.h
+++ b/include/llvm-libc-types/sigset_t.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIGSET_T_H__
-#define __LLVM_LIBC_TYPES_SIGSET_T_H__
+#ifndef LLVM_LIBC_TYPES_SIGSET_T_H
+#define LLVM_LIBC_TYPES_SIGSET_T_H
-#include <llvm-libc-macros/signal-macros.h>
+#include "llvm-libc-macros/signal-macros.h"
// This definition can be adjusted/specialized for different targets and
// platforms as necessary. This definition works for Linux on most targets.
@@ -17,4 +17,4 @@ typedef struct {
unsigned long __signals[__NSIGSET_WORDS];
} sigset_t;
-#endif // __LLVM_LIBC_TYPES_SIGSET_T_H__
+#endif // LLVM_LIBC_TYPES_SIGSET_T_H
diff --git a/include/llvm-libc-types/size_t.h b/include/llvm-libc-types/size_t.h
index 8eaf194e0572..3b31b0820f23 100644
--- a/include/llvm-libc-types/size_t.h
+++ b/include/llvm-libc-types/size_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIZE_T_H__
-#define __LLVM_LIBC_TYPES_SIZE_T_H__
+#ifndef LLVM_LIBC_TYPES_SIZE_T_H
+#define LLVM_LIBC_TYPES_SIZE_T_H
// Since __need_size_t is defined, we get the definition of size_t from the
// standalone C header stddef.h. Also, because __need_size_t is defined,
@@ -16,4 +16,4 @@
#include <stddef.h>
#undef __need_size_t
-#endif // __LLVM_LIBC_TYPES_SIZE_T_H__
+#endif // LLVM_LIBC_TYPES_SIZE_T_H
diff --git a/include/llvm-libc-types/socklen_t.h b/include/llvm-libc-types/socklen_t.h
index 3134a53390e7..5357747f5b83 100644
--- a/include/llvm-libc-types/socklen_t.h
+++ b/include/llvm-libc-types/socklen_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SOCKLEN_T_H__
-#define __LLVM_LIBC_TYPES_SOCKLEN_T_H__
+#ifndef LLVM_LIBC_TYPES_SOCKLEN_T_H
+#define LLVM_LIBC_TYPES_SOCKLEN_T_H
// The posix standard only says of socklen_t that it must be an integer type of
// width of at least 32 bits. The long type is defined as being at least 32
@@ -15,4 +15,4 @@
typedef unsigned long socklen_t;
-#endif // __LLVM_LIBC_TYPES_SOCKLEN_T_H__
+#endif // LLVM_LIBC_TYPES_SOCKLEN_T_H
diff --git a/include/llvm-libc-types/speed_t.h b/include/llvm-libc-types/speed_t.h
index b4ec13df27b5..9875d3b82a69 100644
--- a/include/llvm-libc-types/speed_t.h
+++ b/include/llvm-libc-types/speed_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SPEED_T_H__
-#define __LLVM_LIBC_TYPES_SPEED_T_H__
+#ifndef LLVM_LIBC_TYPES_SPEED_T_H
+#define LLVM_LIBC_TYPES_SPEED_T_H
typedef unsigned int speed_t;
-#endif // __LLVM_LIBC_TYPES_SPEED_T_H__
+#endif // LLVM_LIBC_TYPES_SPEED_T_H
diff --git a/include/llvm-libc-types/ssize_t.h b/include/llvm-libc-types/ssize_t.h
index b8874538b1bf..41e4b6d2c500 100644
--- a/include/llvm-libc-types/ssize_t.h
+++ b/include/llvm-libc-types/ssize_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SSIZE_T_H__
-#define __LLVM_LIBC_TYPES_SSIZE_T_H__
+#ifndef LLVM_LIBC_TYPES_SSIZE_T_H
+#define LLVM_LIBC_TYPES_SSIZE_T_H
typedef __INT64_TYPE__ ssize_t;
-#endif // __LLVM_LIBC_TYPES_SSIZE_T_H__
+#endif // LLVM_LIBC_TYPES_SSIZE_T_H
diff --git a/include/llvm-libc-types/stack_t.h b/include/llvm-libc-types/stack_t.h
index f564d9134010..9156425436e9 100644
--- a/include/llvm-libc-types/stack_t.h
+++ b/include/llvm-libc-types/stack_t.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STACK_T_H__
-#define __LLVM_LIBC_TYPES_STACK_T_H__
+#ifndef LLVM_LIBC_TYPES_STACK_T_H
+#define LLVM_LIBC_TYPES_STACK_T_H
-#include <llvm-libc-types/size_t.h>
+#include "llvm-libc-types/size_t.h"
typedef struct {
// The order of the fields declared here should match the kernel definition
@@ -19,4 +19,4 @@ typedef struct {
size_t ss_size;
} stack_t;
-#endif // __LLVM_LIBC_TYPES_STACK_T_H__
+#endif // LLVM_LIBC_TYPES_STACK_T_H
diff --git a/include/llvm-libc-types/struct_dirent.h b/include/llvm-libc-types/struct_dirent.h
index de54a2262446..0bb71b9f3b84 100644
--- a/include/llvm-libc-types/struct_dirent.h
+++ b/include/llvm-libc-types/struct_dirent.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_DIRENT_H__
-#define __LLVM_LIBC_TYPES_STRUCT_DIRENT_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_DIRENT_H
+#define LLVM_LIBC_TYPES_STRUCT_DIRENT_H
-#include <llvm-libc-types/ino_t.h>
-#include <llvm-libc-types/off_t.h>
+#include "llvm-libc-types/ino_t.h"
+#include "llvm-libc-types/off_t.h"
struct dirent {
ino_t d_ino;
@@ -26,4 +26,4 @@ struct dirent {
char d_name[1];
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_DIRENT_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_DIRENT_H
diff --git a/include/llvm-libc-types/struct_epoll_data.h b/include/llvm-libc-types/struct_epoll_data.h
new file mode 100644
index 000000000000..7200276a141e
--- /dev/null
+++ b/include/llvm-libc-types/struct_epoll_data.h
@@ -0,0 +1,21 @@
+//===-- Definition of epoll_data 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_STRUCT_EPOLL_DATA_H
+#define LLVM_LIBC_TYPES_STRUCT_EPOLL_DATA_H
+
+union epoll_data {
+ void *ptr;
+ int fd;
+ __UINT32_TYPE__ u32;
+ __UINT64_TYPE__ u64;
+};
+
+typedef union epoll_data epoll_data_t;
+
+#endif // LLVM_LIBC_TYPES_STRUCT_EPOLL_DATA_H
diff --git a/include/llvm-libc-types/struct_epoll_event.h b/include/llvm-libc-types/struct_epoll_event.h
new file mode 100644
index 000000000000..66cf86c1e2a0
--- /dev/null
+++ b/include/llvm-libc-types/struct_epoll_event.h
@@ -0,0 +1,19 @@
+//===-- Definition of epoll_event 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_STRUCT_EPOLL_EVENT_H
+#define LLVM_LIBC_TYPES_STRUCT_EPOLL_EVENT_H
+
+#include "llvm-libc-types/struct_epoll_data.h"
+
+typedef struct epoll_event {
+ __UINT32_TYPE__ events;
+ epoll_data_t data;
+} epoll_event;
+
+#endif // LLVM_LIBC_TYPES_STRUCT_EPOLL_EVENT_H
diff --git a/include/llvm-libc-types/struct_hsearch_data.h b/include/llvm-libc-types/struct_hsearch_data.h
index 7e2a7232fce5..cdb1d0c5da14 100644
--- a/include/llvm-libc-types/struct_hsearch_data.h
+++ b/include/llvm-libc-types/struct_hsearch_data.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H__
-#define __LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H
+#define LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H
struct hsearch_data {
void *__opaque;
unsigned int __unused[2];
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_HSEARCH_DATA_H
diff --git a/include/llvm-libc-types/struct_rlimit.h b/include/llvm-libc-types/struct_rlimit.h
index 4fe0aa6cdf0b..11e6bee15f9d 100644
--- a/include/llvm-libc-types/struct_rlimit.h
+++ b/include/llvm-libc-types/struct_rlimit.h
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_RLIMIT_H__
-#define __LLVM_LIBC_TYPES_STRUCT_RLIMIT_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_RLIMIT_H
+#define LLVM_LIBC_TYPES_STRUCT_RLIMIT_H
-#include <llvm-libc-types/rlim_t.h>
+#include "llvm-libc-types/rlim_t.h"
struct rlimit {
rlim_t rlim_cur;
rlim_t rlim_max;
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_RLIMIT_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_RLIMIT_H
diff --git a/include/llvm-libc-types/struct_rusage.h b/include/llvm-libc-types/struct_rusage.h
index 43f345792205..ed838d30ede3 100644
--- a/include/llvm-libc-types/struct_rusage.h
+++ b/include/llvm-libc-types/struct_rusage.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__
-#define __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_RUSAGE_H
+#define LLVM_LIBC_TYPES_STRUCT_RUSAGE_H
-#include <llvm-libc-types/struct_timeval.h>
+#include "llvm-libc-types/struct_timeval.h"
struct rusage {
struct timeval ru_utime;
@@ -34,4 +34,4 @@ struct rusage {
#endif
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_RUSAGE_H
diff --git a/include/llvm-libc-types/struct_sched_param.h b/include/llvm-libc-types/struct_sched_param.h
index 4f31881ceeb6..86209ac3a181 100644
--- a/include/llvm-libc-types/struct_sched_param.h
+++ b/include/llvm-libc-types/struct_sched_param.h
@@ -6,16 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H__
-#define __LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H
+#define LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H
-#include <llvm-libc-types/pid_t.h>
-#include <llvm-libc-types/struct_timespec.h>
-#include <llvm-libc-types/time_t.h>
+#include "llvm-libc-types/pid_t.h"
+#include "llvm-libc-types/struct_timespec.h"
+#include "llvm-libc-types/time_t.h"
struct sched_param {
// Process or thread execution scheduling priority.
int sched_priority;
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_SCHED_PARAM_H
diff --git a/include/llvm-libc-types/struct_sigaction.h b/include/llvm-libc-types/struct_sigaction.h
index 3940f14ffa84..ffce04d0f7e8 100644
--- a/include/llvm-libc-types/struct_sigaction.h
+++ b/include/llvm-libc-types/struct_sigaction.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SIGACTION_H__
-#define __LLVM_LIBC_TYPES_SIGACTION_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_SIGACTION_H
+#define LLVM_LIBC_TYPES_STRUCT_SIGACTION_H
-#include <llvm-libc-types/siginfo_t.h>
-#include <llvm-libc-types/sigset_t.h>
+#include "llvm-libc-types/siginfo_t.h"
+#include "llvm-libc-types/sigset_t.h"
struct sigaction {
union {
@@ -27,4 +27,4 @@ struct sigaction {
typedef void (*__sighandler_t)(int);
-#endif // __LLVM_LIBC_TYPES_SIGACTION_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_SIGACTION_H
diff --git a/include/llvm-libc-types/struct_sockaddr.h b/include/llvm-libc-types/struct_sockaddr.h
index 9a6214c7d3e6..a98606323c52 100644
--- a/include/llvm-libc-types/struct_sockaddr.h
+++ b/include/llvm-libc-types/struct_sockaddr.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__
-#define __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H
+#define LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H
-#include <llvm-libc-types/sa_family_t.h>
+#include "llvm-libc-types/sa_family_t.h"
struct sockaddr {
sa_family_t sa_family;
@@ -18,4 +18,4 @@ struct sockaddr {
char sa_data[];
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H
diff --git a/include/llvm-libc-types/struct_sockaddr_un.h b/include/llvm-libc-types/struct_sockaddr_un.h
index 9c3efea27925..3c0362ce24fb 100644
--- a/include/llvm-libc-types/struct_sockaddr_un.h
+++ b/include/llvm-libc-types/struct_sockaddr_un.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__
-#define __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H
+#define LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H
-#include <llvm-libc-types/sa_family_t.h>
+#include "llvm-libc-types/sa_family_t.h"
// This is the sockaddr specialization for AF_UNIX or AF_LOCAL sockets, as
// defined by posix.
@@ -19,4 +19,4 @@ struct sockaddr_un {
char sun_path[108]; /* Pathname */
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H
diff --git a/include/llvm-libc-types/struct_stat.h b/include/llvm-libc-types/struct_stat.h
index baaef15d9964..d8ae9dd6ffdc 100644
--- a/include/llvm-libc-types/struct_stat.h
+++ b/include/llvm-libc-types/struct_stat.h
@@ -6,19 +6,19 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_STAT_H__
-#define __LLVM_LIBC_TYPES_STRUCT_STAT_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_STAT_H
+#define LLVM_LIBC_TYPES_STRUCT_STAT_H
-#include <llvm-libc-types/blkcnt_t.h>
-#include <llvm-libc-types/blksize_t.h>
-#include <llvm-libc-types/dev_t.h>
-#include <llvm-libc-types/gid_t.h>
-#include <llvm-libc-types/ino_t.h>
-#include <llvm-libc-types/mode_t.h>
-#include <llvm-libc-types/nlink_t.h>
-#include <llvm-libc-types/off_t.h>
-#include <llvm-libc-types/struct_timespec.h>
-#include <llvm-libc-types/uid_t.h>
+#include "llvm-libc-types/blkcnt_t.h"
+#include "llvm-libc-types/blksize_t.h"
+#include "llvm-libc-types/dev_t.h"
+#include "llvm-libc-types/gid_t.h"
+#include "llvm-libc-types/ino_t.h"
+#include "llvm-libc-types/mode_t.h"
+#include "llvm-libc-types/nlink_t.h"
+#include "llvm-libc-types/off_t.h"
+#include "llvm-libc-types/struct_timespec.h"
+#include "llvm-libc-types/uid_t.h"
struct stat {
dev_t st_dev;
@@ -36,4 +36,4 @@ struct stat {
blkcnt_t st_blocks;
};
-#endif // __LLVM_LIBC_TYPES_STRUCT_STAT_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_STAT_H
diff --git a/include/llvm-libc-types/struct_statvfs.h b/include/llvm-libc-types/struct_statvfs.h
new file mode 100644
index 000000000000..f467cfd936bd
--- /dev/null
+++ b/include/llvm-libc-types/struct_statvfs.h
@@ -0,0 +1,29 @@
+//===-- Definition of type struct statvfs ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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_STRUCT_STATVFS_H
+#define LLVM_LIBC_TYPES_STRUCT_STATVFS_H
+
+#include <llvm-libc-types/fsblkcnt_t.h>
+#include <llvm-libc-types/fsfilcnt_t.h>
+
+struct statvfs {
+ unsigned long f_bsize; /* Filesystem block size */
+ unsigned long f_frsize; /* Fragment size */
+ fsblkcnt_t f_blocks; /* Size of fs in f_frsize units */
+ fsblkcnt_t f_bfree; /* Number of free blocks */
+ fsblkcnt_t f_bavail; /* Number of free blocks for unprivileged users */
+ fsfilcnt_t f_files; /* Number of inodes */
+ fsfilcnt_t f_ffree; /* Number of free inodes */
+ fsfilcnt_t f_favail; /* Number of free inodes for unprivileged users */
+ unsigned long f_fsid; /* Filesystem ID */
+ unsigned long f_flag; /* Mount flags */
+ unsigned long f_namemax; /* Maximum filename length */
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_STATVFS_H
diff --git a/include/llvm-libc-types/struct_termios.h b/include/llvm-libc-types/struct_termios.h
index 72aefe4f6926..51241192f741 100644
--- a/include/llvm-libc-types/struct_termios.h
+++ b/include/llvm-libc-types/struct_termios.h
@@ -9,9 +9,9 @@
#ifndef __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__
#define __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__
-#include <llvm-libc-types/cc_t.h>
-#include <llvm-libc-types/speed_t.h>
-#include <llvm-libc-types/tcflag_t.h>
+#include "llvm-libc-types/cc_t.h"
+#include "llvm-libc-types/speed_t.h"
+#include "llvm-libc-types/tcflag_t.h"
struct termios {
tcflag_t c_iflag; // Input mode flags
diff --git a/include/llvm-libc-types/struct_timespec.h b/include/llvm-libc-types/struct_timespec.h
index 1fa6272d3df9..4baab07c10f8 100644
--- a/include/llvm-libc-types/struct_timespec.h
+++ b/include/llvm-libc-types/struct_timespec.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TIMESPEC_H__
-#define __LLVM_LIBC_TYPES_TIMESPEC_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
+#define LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
-#include <llvm-libc-types/time_t.h>
+#include "llvm-libc-types/time_t.h"
struct timespec {
time_t tv_sec; /* Seconds. */
@@ -17,4 +17,4 @@ struct timespec {
long tv_nsec; /* Nanoseconds. */
};
-#endif // __LLVM_LIBC_TYPES_TIMESPEC_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
diff --git a/include/llvm-libc-types/struct_timeval.h b/include/llvm-libc-types/struct_timeval.h
index 756fecabb6ac..365b835d345d 100644
--- a/include/llvm-libc-types/struct_timeval.h
+++ b/include/llvm-libc-types/struct_timeval.h
@@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TIMEVAL_H__
-#define __LLVM_LIBC_TYPES_TIMEVAL_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
+#define LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
-#include <llvm-libc-types/suseconds_t.h>
-#include <llvm-libc-types/time_t.h>
+#include "llvm-libc-types/suseconds_t.h"
+#include "llvm-libc-types/time_t.h"
struct timeval {
time_t tv_sec; // Seconds
suseconds_t tv_usec; // Micro seconds
};
-#endif // __LLVM_LIBC_TYPES_TIMEVAL_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
diff --git a/include/llvm-libc-types/struct_tm.h b/include/llvm-libc-types/struct_tm.h
index 953e12e819c3..9fef7c5718ea 100644
--- a/include/llvm-libc-types/struct_tm.h
+++ b/include/llvm-libc-types/struct_tm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TM_H__
-#define __LLVM_LIBC_TYPES_TM_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_TM_H
+#define LLVM_LIBC_TYPES_STRUCT_TM_H
struct tm {
int tm_sec; // seconds after the minute
@@ -21,4 +21,4 @@ struct tm {
int tm_isdst; // Daylight Saving Time flag
};
-#endif // __LLVM_LIBC_TYPES_TM_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_TM_H
diff --git a/include/llvm-libc-types/struct_utsname.h b/include/llvm-libc-types/struct_utsname.h
index bfd1ad9ceddb..e474171c7285 100644
--- a/include/llvm-libc-types/struct_utsname.h
+++ b/include/llvm-libc-types/struct_utsname.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_STRUCT_UTSNAME_H__
-#define __LLVM_LIBC_TYPES_STRUCT_UTSNAME_H__
+#ifndef LLVM_LIBC_TYPES_STRUCT_UTSNAME_H
+#define LLVM_LIBC_TYPES_STRUCT_UTSNAME_H
#if defined(__linux__)
#define __UTS_NAME_LENGTH 65
@@ -31,4 +31,4 @@ struct utsname {
#undef __UTS_NAME_LENGTH
-#endif // __LLVM_LIBC_TYPES_STRUCT_UTSNAME_H__
+#endif // LLVM_LIBC_TYPES_STRUCT_UTSNAME_H
diff --git a/include/llvm-libc-types/suseconds_t.h b/include/llvm-libc-types/suseconds_t.h
index d7298ed74a4c..32ecc9f537d0 100644
--- a/include/llvm-libc-types/suseconds_t.h
+++ b/include/llvm-libc-types/suseconds_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_SUSECONDS_T_H__
-#define __LLVM_LIBC_TYPES_SUSECONDS_T_H__
+#ifndef LLVM_LIBC_TYPES_SUSECONDS_T_H
+#define LLVM_LIBC_TYPES_SUSECONDS_T_H
typedef __INT32_TYPE__ suseconds_t;
-#endif // __LLVM_LIBC_TYPES_SUSECONDS_T_H__
+#endif // LLVM_LIBC_TYPES_SUSECONDS_T_H
diff --git a/include/llvm-libc-types/tcflag_t.h b/include/llvm-libc-types/tcflag_t.h
index 7c2ce2154208..2978487df434 100644
--- a/include/llvm-libc-types/tcflag_t.h
+++ b/include/llvm-libc-types/tcflag_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TCFLAG_T_H__
-#define __LLVM_LIBC_TYPES_TCFLAG_T_H__
+#ifndef LLVM_LIBC_TYPES_TCFLAG_T_H
+#define LLVM_LIBC_TYPES_TCFLAG_T_H
typedef unsigned int tcflag_t;
-#endif // __LLVM_LIBC_TYPES_TCFLAG_T_H__
+#endif // LLVM_LIBC_TYPES_TCFLAG_T_H
diff --git a/include/llvm-libc-types/test_rpc_opcodes_t.h b/include/llvm-libc-types/test_rpc_opcodes_t.h
index ec4eb2608799..7129768dc8b9 100644
--- a/include/llvm-libc-types/test_rpc_opcodes_t.h
+++ b/include/llvm-libc-types/test_rpc_opcodes_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TEST_RPC_OPCODE_H__
-#define __LLVM_LIBC_TYPES_TEST_RPC_OPCODE_H__
+#ifndef LLVM_LIBC_TYPES_TEST_RPC_OPCODES_T_H
+#define LLVM_LIBC_TYPES_TEST_RPC_OPCODES_T_H
// We consider the first 32768 opcodes as reserved for libc purposes. We allow
// extensions to use any other number without conflicting with anything else.
@@ -18,4 +18,4 @@ typedef enum : unsigned short {
RPC_TEST_STREAM,
} rpc_test_opcode_t;
-#endif // __LLVM_LIBC_TYPES_TEST_RPC_OPCODE_H__
+#endif // LLVM_LIBC_TYPES_TEST_RPC_OPCODES_T_H
diff --git a/include/llvm-libc-types/thrd_start_t.h b/include/llvm-libc-types/thrd_start_t.h
index 83fc32cbd1f8..1fb21bccc036 100644
--- a/include/llvm-libc-types/thrd_start_t.h
+++ b/include/llvm-libc-types/thrd_start_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_THRD_START_T_H__
-#define __LLVM_LIBC_TYPES_THRD_START_T_H__
+#ifndef LLVM_LIBC_TYPES_THRD_START_T_H
+#define LLVM_LIBC_TYPES_THRD_START_T_H
typedef int (*thrd_start_t)(void *);
-#endif // __LLVM_LIBC_TYPES_THRD_START_T_H__
+#endif // LLVM_LIBC_TYPES_THRD_START_T_H
diff --git a/include/llvm-libc-types/thrd_t.h b/include/llvm-libc-types/thrd_t.h
index 0743106c48c6..751ea5b9e4c0 100644
--- a/include/llvm-libc-types/thrd_t.h
+++ b/include/llvm-libc-types/thrd_t.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_THRD_T_H__
-#define __LLVM_LIBC_TYPES_THRD_T_H__
+#ifndef LLVM_LIBC_TYPES_THRD_T_H
+#define LLVM_LIBC_TYPES_THRD_T_H
-#include <llvm-libc-types/__thread_type.h>
+#include "llvm-libc-types/__thread_type.h"
typedef __thread_type thrd_t;
-#endif // __LLVM_LIBC_TYPES_THRD_T_H__
+#endif // LLVM_LIBC_TYPES_THRD_T_H
diff --git a/include/llvm-libc-types/time_t.h b/include/llvm-libc-types/time_t.h
index 2b3ccd4d8024..59953b343ba9 100644
--- a/include/llvm-libc-types/time_t.h
+++ b/include/llvm-libc-types/time_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TIME_T_H__
-#define __LLVM_LIBC_TYPES_TIME_T_H__
+#ifndef LLVM_LIBC_TYPES_TIME_T_H
+#define LLVM_LIBC_TYPES_TIME_T_H
#if (defined(__arm__) || defined(_M_ARM))
typedef __INTPTR_TYPE__ time_t;
@@ -15,4 +15,4 @@ typedef __INTPTR_TYPE__ time_t;
typedef __INT64_TYPE__ time_t;
#endif
-#endif // __LLVM_LIBC_TYPES_TIME_T_H__
+#endif // LLVM_LIBC_TYPES_TIME_T_H
diff --git a/include/llvm-libc-types/tss_dtor_t.h b/include/llvm-libc-types/tss_dtor_t.h
index f80661b588ba..c54b34e7d8b7 100644
--- a/include/llvm-libc-types/tss_dtor_t.h
+++ b/include/llvm-libc-types/tss_dtor_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TSS_DTOR_T_H__
-#define __LLVM_LIBC_TYPES_TSS_DTOR_T_H__
+#ifndef LLVM_LIBC_TYPES_TSS_DTOR_T_H
+#define LLVM_LIBC_TYPES_TSS_DTOR_T_H
typedef void (*tss_dtor_t)(void *);
-#endif // __LLVM_LIBC_TYPES_TSS_DTOR_T_H__
+#endif // LLVM_LIBC_TYPES_TSS_DTOR_T_H
diff --git a/include/llvm-libc-types/tss_t.h b/include/llvm-libc-types/tss_t.h
index 868ec1ac1128..92bc7ef451ca 100644
--- a/include/llvm-libc-types/tss_t.h
+++ b/include/llvm-libc-types/tss_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_TSS_T_H__
-#define __LLVM_LIBC_TYPES_TSS_T_H__
+#ifndef LLVM_LIBC_TYPES_TSS_T_H
+#define LLVM_LIBC_TYPES_TSS_T_H
typedef unsigned int tss_t;
-#endif // __LLVM_LIBC_TYPES_TSS_T_H__
+#endif // LLVM_LIBC_TYPES_TSS_T_H
diff --git a/include/llvm-libc-types/uid_t.h b/include/llvm-libc-types/uid_t.h
index ae9fac2a4288..4f6c6479186b 100644
--- a/include/llvm-libc-types/uid_t.h
+++ b/include/llvm-libc-types/uid_t.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_UID_T_H__
-#define __LLVM_LIBC_TYPES_UID_T_H__
+#ifndef LLVM_LIBC_TYPES_UID_T_H
+#define LLVM_LIBC_TYPES_UID_T_H
typedef __UINT32_TYPE__ uid_t;
-#endif // __LLVM_LIBC_TYPES_UID_T_H__
+#endif // LLVM_LIBC_TYPES_UID_T_H
diff --git a/include/llvm-libc-types/union_sigval.h b/include/llvm-libc-types/union_sigval.h
index ccc9f2e5d0fb..5f83cd220308 100644
--- a/include/llvm-libc-types/union_sigval.h
+++ b/include/llvm-libc-types/union_sigval.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_UNION_SIGVAL_H__
-#define __LLVM_LIBC_TYPES_UNION_SIGVAL_H__
+#ifndef LLVM_LIBC_TYPES_UNION_SIGVAL_H
+#define LLVM_LIBC_TYPES_UNION_SIGVAL_H
union sigval {
int sival_int;
void *sival_ptr;
};
-#endif // __LLVM_LIBC_TYPES_UNION_SIGVAL_H__
+#endif // LLVM_LIBC_TYPES_UNION_SIGVAL_H
diff --git a/include/llvm-libc-types/wchar_t.h b/include/llvm-libc-types/wchar_t.h
index 9efb5cd8e665..3e9a70b8afe6 100644
--- a/include/llvm-libc-types/wchar_t.h
+++ b/include/llvm-libc-types/wchar_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_WCHAR_T_H__
-#define __LLVM_LIBC_TYPES_WCHAR_T_H__
+#ifndef LLVM_LIBC_TYPES_WCHAR_T_H
+#define LLVM_LIBC_TYPES_WCHAR_T_H
// Since __need_wchar_t is defined, we get the definition of wchar_t from the
// standalone C header stddef.h. Also, because __need_wchar_t is defined,
@@ -16,4 +16,4 @@
#include <stddef.h>
#undef __need_wchar_t
-#endif // __LLVM_LIBC_TYPES_WCHAR_T_H__
+#endif // LLVM_LIBC_TYPES_WCHAR_T_H
diff --git a/include/llvm-libc-types/wint_t.h b/include/llvm-libc-types/wint_t.h
index cf6ccd7e1ae7..2758685a0845 100644
--- a/include/llvm-libc-types/wint_t.h
+++ b/include/llvm-libc-types/wint_t.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __LLVM_LIBC_TYPES_WINT_T_H__
-#define __LLVM_LIBC_TYPES_WINT_T_H__
+#ifndef LLVM_LIBC_TYPES_WINT_T_H
+#define LLVM_LIBC_TYPES_WINT_T_H
// Since __need_wint_t is defined, we get the definition of wint_t from the
// standalone C header stddef.h. Also, because __need_wint_t is defined,
@@ -16,4 +16,4 @@
#include <stddef.h>
#undef __need_wint_t
-#endif // __LLVM_LIBC_TYPES_WINT_T_H__
+#endif // LLVM_LIBC_TYPES_WINT_T_H
diff --git a/include/sys/queue.h b/include/sys/queue.h
index 2a4dc37712d6..cca53c16f0f3 100644
--- a/include/sys/queue.h
+++ b/include/sys/queue.h
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SYS_QUEUE_H
-#define LLVM_LIBC_SYS_QUEUE_H
+#ifndef SYS_QUEUE_H
+#define SYS_QUEUE_H
-#include <llvm-libc-macros/sys-queue-macros.h>
+#include "llvm-libc-macros/sys-queue-macros.h"
-#endif // LLVM_LIBC_SYS_QUEUE_H
+#endif // SYS_QUEUE_H
diff --git a/src/__support/CPP/array.h b/src/__support/CPP/array.h
index 12e574899988..4e69ba003e80 100644
--- a/src/__support/CPP/array.h
+++ b/src/__support/CPP/array.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_ARRAY_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_ARRAY_H
+#include "src/__support/CPP/iterator.h" // reverse_iterator
#include "src/__support/macros/attributes.h"
#include <stddef.h> // For size_t.
@@ -23,15 +24,17 @@ template <class T, size_t N> struct array {
using value_type = T;
using iterator = T *;
using const_iterator = const T *;
+ using reverse_iterator = cpp::reverse_iterator<iterator>;
+ using const_reverse_iterator = cpp::reverse_iterator<const_iterator>;
LIBC_INLINE constexpr T *data() { return Data; }
LIBC_INLINE constexpr const T *data() const { return Data; }
LIBC_INLINE constexpr T &front() { return Data[0]; }
- LIBC_INLINE constexpr T &front() const { return Data[0]; }
+ LIBC_INLINE constexpr const T &front() const { return Data[0]; }
LIBC_INLINE constexpr T &back() { return Data[N - 1]; }
- LIBC_INLINE constexpr T &back() const { return Data[N - 1]; }
+ LIBC_INLINE constexpr const T &back() const { return Data[N - 1]; }
LIBC_INLINE constexpr T &operator[](size_t Index) { return Data[Index]; }
@@ -45,9 +48,29 @@ template <class T, size_t N> struct array {
LIBC_INLINE constexpr iterator begin() { return Data; }
LIBC_INLINE constexpr const_iterator begin() const { return Data; }
+ LIBC_INLINE constexpr const_iterator cbegin() const { return begin(); }
LIBC_INLINE constexpr iterator end() { return Data + N; }
- LIBC_INLINE const_iterator end() const { return Data + N; }
+ LIBC_INLINE constexpr const_iterator end() const { return Data + N; }
+ LIBC_INLINE constexpr const_iterator cend() const { return end(); }
+
+ LIBC_INLINE constexpr reverse_iterator rbegin() {
+ return reverse_iterator{end()};
+ }
+ LIBC_INLINE constexpr const_reverse_iterator rbegin() const {
+ return const_reverse_iterator{end()};
+ }
+ LIBC_INLINE constexpr const_reverse_iterator crbegin() const {
+ return rbegin();
+ }
+
+ LIBC_INLINE constexpr reverse_iterator rend() {
+ return reverse_iterator{begin()};
+ }
+ LIBC_INLINE constexpr const_reverse_iterator rend() const {
+ return const_reverse_iterator{begin()};
+ }
+ LIBC_INLINE constexpr const_reverse_iterator crend() const { return rend(); }
};
} // namespace cpp
diff --git a/src/__support/CPP/atomic.h b/src/__support/CPP/atomic.h
index 1c4478dfeab6..5e428940565b 100644
--- a/src/__support/CPP/atomic.h
+++ b/src/__support/CPP/atomic.h
@@ -71,10 +71,11 @@ public:
T load(MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_load_n))
- return __scoped_atomic_load_n(&val, int(mem_ord), (int)(mem_scope));
- else
- return __atomic_load_n(&val, int(mem_ord));
+#if __has_builtin(__scoped_atomic_load_n)
+ return __scoped_atomic_load_n(&val, int(mem_ord), (int)(mem_scope));
+#else
+ return __atomic_load_n(&val, int(mem_ord));
+#endif
}
// Atomic store.
@@ -85,10 +86,11 @@ public:
void store(T rhs, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_store_n))
- __scoped_atomic_store_n(&val, rhs, int(mem_ord), (int)(mem_scope));
- else
- __atomic_store_n(&val, rhs, int(mem_ord));
+#if __has_builtin(__scoped_atomic_store_n)
+ __scoped_atomic_store_n(&val, rhs, int(mem_ord), (int)(mem_scope));
+#else
+ __atomic_store_n(&val, rhs, int(mem_ord));
+#endif
}
// Atomic compare exchange
@@ -101,47 +103,51 @@ public:
T exchange(T desired, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_exchange_n))
- return __scoped_atomic_exchange_n(&val, desired, int(mem_ord),
- (int)(mem_scope));
- else
- return __atomic_exchange_n(&val, desired, int(mem_ord));
+#if __has_builtin(__scoped_atomic_exchange_n)
+ return __scoped_atomic_exchange_n(&val, desired, int(mem_ord),
+ (int)(mem_scope));
+#else
+ return __atomic_exchange_n(&val, desired, int(mem_ord));
+#endif
}
T fetch_add(T increment, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_fetch_add))
- return __scoped_atomic_fetch_add(&val, increment, int(mem_ord),
- (int)(mem_scope));
- else
- return __atomic_fetch_add(&val, increment, int(mem_ord));
+#if __has_builtin(__scoped_atomic_fetch_add)
+ return __scoped_atomic_fetch_add(&val, increment, int(mem_ord),
+ (int)(mem_scope));
+#else
+ return __atomic_fetch_add(&val, increment, int(mem_ord));
+#endif
}
T fetch_or(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_fetch_or))
- return __scoped_atomic_fetch_or(&val, mask, int(mem_ord),
- (int)(mem_scope));
- else
- return __atomic_fetch_or(&val, mask, int(mem_ord));
+#if __has_builtin(__scoped_atomic_fetch_or)
+ return __scoped_atomic_fetch_or(&val, mask, int(mem_ord), (int)(mem_scope));
+#else
+ return __atomic_fetch_or(&val, mask, int(mem_ord));
+#endif
}
T fetch_and(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_fetch_and))
- return __scoped_atomic_fetch_and(&val, mask, int(mem_ord),
- (int)(mem_scope));
- else
- return __atomic_fetch_and(&val, mask, int(mem_ord));
+#if __has_builtin(__scoped_atomic_fetch_and)
+ return __scoped_atomic_fetch_and(&val, mask, int(mem_ord),
+ (int)(mem_scope));
+#else
+ return __atomic_fetch_and(&val, mask, int(mem_ord));
+#endif
}
T fetch_sub(T decrement, MemoryOrder mem_ord = MemoryOrder::SEQ_CST,
[[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) {
- if constexpr (LIBC_HAS_BUILTIN(__scoped_atomic_fetch_sub))
- return __scoped_atomic_fetch_sub(&val, decrement, int(mem_ord),
- (int)(mem_scope));
- else
- return __atomic_fetch_sub(&val, decrement, int(mem_ord));
+#if __has_builtin(__scoped_atomic_fetch_sub)
+ return __scoped_atomic_fetch_sub(&val, decrement, int(mem_ord),
+ (int)(mem_scope));
+#else
+ return __atomic_fetch_sub(&val, decrement, int(mem_ord));
+#endif
}
// Set the value without using an atomic operation. This is useful
@@ -150,14 +156,27 @@ public:
};
// Issue a thread fence with the given memory ordering.
-LIBC_INLINE void atomic_thread_fence(MemoryOrder mem_ord) {
+LIBC_INLINE void atomic_thread_fence([[maybe_unused]] MemoryOrder mem_ord) {
// The NVPTX backend currently does not support atomic thread fences so we use a
// full system fence instead.
#ifdef LIBC_TARGET_ARCH_IS_NVPTX
- (void)mem_ord;
__nvvm_membar_sys();
#else
- __atomic_thread_fence(int(mem_ord));
+ __atomic_thread_fence(static_cast<int>(mem_ord));
+#endif
+}
+
+// Establishes memory synchronization ordering of non-atomic and relaxed atomic
+// accesses, as instructed by order, between a thread and a signal handler
+// executed on the same thread. This is equivalent to atomic_thread_fence,
+// except no instructions for memory ordering are issued. Only reordering of
+// the instructions by the compiler is suppressed as order instructs.
+LIBC_INLINE void atomic_signal_fence([[maybe_unused]] MemoryOrder mem_ord) {
+#if __has_builtin(__atomic_signal_fence)
+ __atomic_signal_fence(static_cast<int>(mem_ord));
+#else
+ // if the builtin is not ready, use asm as a full compiler barrier.
+ asm volatile("" ::: "memory");
#endif
}
diff --git a/src/__support/CPP/bit.h b/src/__support/CPP/bit.h
index 122f6b8c3328..80f50fd221ef 100644
--- a/src/__support/CPP/bit.h
+++ b/src/__support/CPP/bit.h
@@ -14,45 +14,47 @@
#include "src/__support/CPP/limits.h" // numeric_limits
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
#include "src/__support/macros/sanitizer.h"
#include <stdint.h>
namespace LIBC_NAMESPACE::cpp {
-#if LIBC_HAS_BUILTIN(__builtin_memcpy_inline)
+#if __has_builtin(__builtin_memcpy_inline)
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
#endif
// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
-template <
- typename To, typename From,
- typename = cpp::enable_if_t<sizeof(To) == sizeof(From) &&
- cpp::is_trivially_constructible<To>::value &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<From>::value>>
-LIBC_INLINE constexpr To bit_cast(const From &from) {
+template <typename To, typename From>
+LIBC_INLINE constexpr cpp::enable_if_t<
+ (sizeof(To) == sizeof(From)) &&
+ cpp::is_trivially_constructible<To>::value &&
+ cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<From>::value,
+ To>
+bit_cast(const From &from) {
MSAN_UNPOISON(&from, sizeof(From));
-#if LIBC_HAS_BUILTIN(__builtin_bit_cast)
+#if __has_builtin(__builtin_bit_cast)
return __builtin_bit_cast(To, from);
#else
To to;
char *dst = reinterpret_cast<char *>(&to);
const char *src = reinterpret_cast<const char *>(&from);
-#if LIBC_HAS_BUILTIN(__builtin_memcpy_inline)
+#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(dst, src, sizeof(To));
#else
for (unsigned i = 0; i < sizeof(To); ++i)
dst[i] = src[i];
-#endif // LIBC_HAS_BUILTIN(__builtin_memcpy_inline)
+#endif // __has_builtin(__builtin_memcpy_inline)
return to;
-#endif // LIBC_HAS_BUILTIN(__builtin_bit_cast)
+#endif // __has_builtin(__builtin_bit_cast)
}
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr bool has_single_bit(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
+ bool>
+has_single_bit(T value) {
return (value != 0) && ((value & (value - 1)) == 0);
}
@@ -70,8 +72,9 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of 0.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr int countr_zero(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+countr_zero(T value) {
if (!value)
return cpp::numeric_limits<T>::digits;
if (value & 0x1)
@@ -90,18 +93,12 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
}
return zero_bits;
}
-#if LIBC_HAS_BUILTIN(__builtin_ctzs)
+#if __has_builtin(__builtin_ctzs)
ADD_SPECIALIZATION(countr_zero, unsigned short, __builtin_ctzs)
#endif
-#if LIBC_HAS_BUILTIN(__builtin_ctz)
ADD_SPECIALIZATION(countr_zero, unsigned int, __builtin_ctz)
-#endif
-#if LIBC_HAS_BUILTIN(__builtin_ctzl)
ADD_SPECIALIZATION(countr_zero, unsigned long, __builtin_ctzl)
-#endif
-#if LIBC_HAS_BUILTIN(__builtin_ctzll)
ADD_SPECIALIZATION(countr_zero, unsigned long long, __builtin_ctzll)
-#endif
/// Count number of 0's from the most significant bit to the least
/// stopping at the first 1.
@@ -109,8 +106,9 @@ ADD_SPECIALIZATION(countr_zero, unsigned long long, __builtin_ctzll)
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of 0.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr int countl_zero(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+countl_zero(T value) {
if (!value)
return cpp::numeric_limits<T>::digits;
// Bisection method.
@@ -125,18 +123,12 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
}
return zero_bits;
}
-#if LIBC_HAS_BUILTIN(__builtin_clzs)
+#if __has_builtin(__builtin_clzs)
ADD_SPECIALIZATION(countl_zero, unsigned short, __builtin_clzs)
#endif
-#if LIBC_HAS_BUILTIN(__builtin_clz)
ADD_SPECIALIZATION(countl_zero, unsigned int, __builtin_clz)
-#endif
-#if LIBC_HAS_BUILTIN(__builtin_clzl)
ADD_SPECIALIZATION(countl_zero, unsigned long, __builtin_clzl)
-#endif
-#if LIBC_HAS_BUILTIN(__builtin_clzll)
ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll)
-#endif
#undef ADD_SPECIALIZATION
@@ -147,8 +139,9 @@ ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll)
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of all ones.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr int countl_one(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+countl_one(T value) {
return cpp::countl_zero<T>(~value);
}
@@ -159,8 +152,9 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of all ones.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr int countr_one(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+countr_one(T value) {
return cpp::countr_zero<T>(~value);
}
@@ -168,8 +162,9 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
/// Returns 0 otherwise.
///
/// Ex. bit_width(5) == 3.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr int bit_width(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+bit_width(T value) {
return cpp::numeric_limits<T>::digits - cpp::countl_zero(value);
}
@@ -177,11 +172,12 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
/// nonzero. Returns 0 otherwise.
///
/// Ex. bit_floor(5) == 4.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr T bit_floor(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+bit_floor(T value) {
if (!value)
return 0;
- return T(1) << (cpp::bit_width(value) - 1);
+ return static_cast<T>(T(1) << (cpp::bit_width(value) - 1));
}
/// Returns the smallest integral power of two no smaller than value if value is
@@ -191,39 +187,43 @@ template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
///
/// The return value is undefined if the input is larger than the largest power
/// of two representable in T.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr T bit_ceil(T value) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+bit_ceil(T value) {
if (value < 2)
return 1;
- return T(1) << cpp::bit_width<T>(value - 1u);
+ return static_cast<T>(T(1) << cpp::bit_width(value - 1U));
}
// Rotate algorithms make use of "Safe, Efficient, and Portable Rotate in C/C++"
// from https://blog.regehr.org/archives/1063.
// Forward-declare rotr so that rotl can use it.
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate);
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+rotr(T value, int rotate);
-template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
-[[nodiscard]] LIBC_INLINE constexpr T rotl(T value, int rotate) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+rotl(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
if (rotate < 0)
- return cpp::rotr(value, -rotate);
+ return cpp::rotr<T>(value, -rotate);
return (value << rotate) | (value >> (N - rotate));
}
-template <typename T, typename>
-[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate) {
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+rotr(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
if (rotate < 0)
- return cpp::rotl(value, -rotate);
+ return cpp::rotl<T>(value, -rotate);
return (value >> rotate) | (value << (N - rotate));
}
@@ -238,6 +238,39 @@ LIBC_INLINE constexpr To bit_or_static_cast(const From &from) {
}
}
+/// Count number of 1's aka population count or Hamming weight.
+///
+/// Only unsigned integral types are allowed.
+// clang-19+, gcc-14+
+#if __has_builtin(__builtin_popcountg)
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+popcount(T value) {
+ return __builtin_popcountg(value);
+}
+#else // !__has_builtin(__builtin_popcountg)
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+popcount(T value) {
+ int count = 0;
+ for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i)
+ if ((value >> i) & 0x1)
+ ++count;
+ return count;
+}
+#define ADD_SPECIALIZATION(TYPE, BUILTIN) \
+ template <> \
+ [[nodiscard]] LIBC_INLINE constexpr int popcount<TYPE>(TYPE value) { \
+ return BUILTIN(value); \
+ }
+ADD_SPECIALIZATION(unsigned char, __builtin_popcount)
+ADD_SPECIALIZATION(unsigned short, __builtin_popcount)
+ADD_SPECIALIZATION(unsigned, __builtin_popcount)
+ADD_SPECIALIZATION(unsigned long, __builtin_popcountl)
+ADD_SPECIALIZATION(unsigned long long, __builtin_popcountll)
+#endif // __builtin_popcountg
+#undef ADD_SPECIALIZATION
+
} // namespace LIBC_NAMESPACE::cpp
#endif // LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
diff --git a/src/__support/CPP/expected.h b/src/__support/CPP/expected.h
index 52174a054f87..9682de981a83 100644
--- a/src/__support/CPP/expected.h
+++ b/src/__support/CPP/expected.h
@@ -33,12 +33,14 @@ public:
constexpr expected(unexpected<E> unexp)
: unexp(unexp.error()), is_expected(false) {}
- constexpr bool has_value() { return is_expected; }
+ constexpr bool has_value() const { return is_expected; }
- constexpr T value() { return exp; }
- constexpr E error() { return unexp; }
+ constexpr T &value() { return exp; }
+ constexpr E &error() { return unexp; }
+ constexpr const T &value() const { return exp; }
+ constexpr const E &error() const { return unexp; }
- constexpr operator bool() { return is_expected; }
+ constexpr operator bool() const { return is_expected; }
constexpr T &operator*() { return exp; }
constexpr const T &operator*() const { return exp; }
diff --git a/src/__support/CPP/iterator.h b/src/__support/CPP/iterator.h
new file mode 100644
index 000000000000..b0fd5c9f22ae
--- /dev/null
+++ b/src/__support/CPP/iterator.h
@@ -0,0 +1,98 @@
+//===-- Standalone implementation of iterator -------------------*- 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_CPP_ITERATOR_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H
+
+#include "src/__support/CPP/type_traits/enable_if.h"
+#include "src/__support/CPP/type_traits/is_convertible.h"
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/macros/attributes.h"
+
+namespace LIBC_NAMESPACE {
+namespace cpp {
+
+template <typename T> struct iterator_traits;
+template <typename T> struct iterator_traits<T *> {
+ using reference = T &;
+ using value_type = T;
+};
+
+template <typename Iter> class reverse_iterator {
+ Iter current;
+
+public:
+ using reference = typename iterator_traits<Iter>::reference;
+ using value_type = typename iterator_traits<Iter>::value_type;
+ using iterator_type = Iter;
+
+ LIBC_INLINE reverse_iterator() : current() {}
+ LIBC_INLINE constexpr explicit reverse_iterator(Iter it) : current(it) {}
+
+ template <typename Other,
+ cpp::enable_if_t<!cpp::is_same_v<Iter, Other> &&
+ cpp::is_convertible_v<const Other &, Iter>,
+ int> = 0>
+ LIBC_INLINE constexpr explicit reverse_iterator(const Other &it)
+ : current(it) {}
+
+ LIBC_INLINE friend constexpr bool operator==(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() == rhs.base();
+ }
+
+ LIBC_INLINE friend constexpr bool operator!=(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() != rhs.base();
+ }
+
+ LIBC_INLINE friend constexpr bool operator<(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() > rhs.base();
+ }
+
+ LIBC_INLINE friend constexpr bool operator<=(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() >= rhs.base();
+ }
+
+ LIBC_INLINE friend constexpr bool operator>(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() < rhs.base();
+ }
+
+ LIBC_INLINE friend constexpr bool operator>=(const reverse_iterator &lhs,
+ const reverse_iterator &rhs) {
+ return lhs.base() <= rhs.base();
+ }
+
+ LIBC_INLINE constexpr iterator_type base() const { return current; }
+
+ LIBC_INLINE constexpr reference operator*() const {
+ Iter tmp = current;
+ return *--tmp;
+ }
+ LIBC_INLINE constexpr reverse_iterator operator--() {
+ ++current;
+ return *this;
+ }
+ LIBC_INLINE constexpr reverse_iterator &operator++() {
+ --current;
+ return *this;
+ }
+ LIBC_INLINE constexpr reverse_iterator operator++(int) {
+ reverse_iterator tmp(*this);
+ --current;
+ return tmp;
+ }
+};
+
+} // namespace cpp
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H
diff --git a/src/__support/CPP/limits.h b/src/__support/CPP/limits.h
index 1ffde5f9556f..5b9b3e755c72 100644
--- a/src/__support/CPP/limits.h
+++ b/src/__support/CPP/limits.h
@@ -12,7 +12,8 @@
#include "include/llvm-libc-macros/limits-macros.h" // CHAR_BIT
#include "src/__support/CPP/type_traits/is_integral.h"
#include "src/__support/CPP/type_traits/is_signed.h"
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
namespace LIBC_NAMESPACE {
namespace cpp {
@@ -76,7 +77,7 @@ template <>
struct numeric_limits<unsigned char>
: public internal::integer_impl<unsigned char, 0, UCHAR_MAX> {};
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
// On platform where UInt128 resolves to __uint128_t, this specialization
// provides the limits of UInt128.
template <>
diff --git a/src/__support/CPP/string_view.h b/src/__support/CPP/string_view.h
index d23aa261ca06..8aa96fa87f69 100644
--- a/src/__support/CPP/string_view.h
+++ b/src/__support/CPP/string_view.h
@@ -179,7 +179,8 @@ public:
LIBC_INLINE char back() const { return Data[Len - 1]; }
// Finds the first occurence of c in this view, starting at position From.
- LIBC_INLINE size_t find_first_of(const char c, size_t From = 0) const {
+ LIBC_INLINE constexpr size_t find_first_of(const char c,
+ size_t From = 0) const {
for (size_t Pos = From; Pos < size(); ++Pos)
if ((*this)[Pos] == c)
return Pos;
@@ -187,13 +188,29 @@ public:
}
// Finds the last occurence of c in this view, ending at position End.
- LIBC_INLINE size_t find_last_of(const char c, size_t End = npos) const {
+ LIBC_INLINE constexpr size_t find_last_of(const char c,
+ size_t End = npos) const {
End = End >= size() ? size() : End + 1;
for (; End > 0; --End)
if ((*this)[End - 1] == c)
return End - 1;
return npos;
}
+
+ // Finds the first character not equal to c in this view, starting at position
+ // From.
+ LIBC_INLINE constexpr size_t find_first_not_of(const char c,
+ size_t From = 0) const {
+ for (size_t Pos = From; Pos < size(); ++Pos)
+ if ((*this)[Pos] != c)
+ return Pos;
+ return npos;
+ }
+
+ // Check if this view contains the given character.
+ LIBC_INLINE constexpr bool contains(char c) const {
+ return find_first_of(c) != npos;
+ }
};
} // namespace cpp
diff --git a/src/__support/CPP/type_traits.h b/src/__support/CPP/type_traits.h
index 1eb2f34ebee3..1494aeb905e0 100644
--- a/src/__support/CPP/type_traits.h
+++ b/src/__support/CPP/type_traits.h
@@ -25,9 +25,11 @@
#include "src/__support/CPP/type_traits/is_base_of.h"
#include "src/__support/CPP/type_traits/is_class.h"
#include "src/__support/CPP/type_traits/is_const.h"
+#include "src/__support/CPP/type_traits/is_constant_evaluated.h"
#include "src/__support/CPP/type_traits/is_convertible.h"
#include "src/__support/CPP/type_traits/is_destructible.h"
#include "src/__support/CPP/type_traits/is_enum.h"
+#include "src/__support/CPP/type_traits/is_fixed_point.h"
#include "src/__support/CPP/type_traits/is_floating_point.h"
#include "src/__support/CPP/type_traits/is_function.h"
#include "src/__support/CPP/type_traits/is_integral.h"
diff --git a/src/__support/CPP/type_traits/add_pointer.h b/src/__support/CPP/type_traits/add_pointer.h
index 72a764bb8ba6..1257033ee80e 100644
--- a/src/__support/CPP/type_traits/add_pointer.h
+++ b/src/__support/CPP/type_traits/add_pointer.h
@@ -10,7 +10,6 @@
#include "src/__support/CPP/type_traits/remove_reference.h"
#include "src/__support/CPP/type_traits/type_identity.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
diff --git a/src/__support/CPP/type_traits/decay.h b/src/__support/CPP/type_traits/decay.h
index a018286fddd8..f1a1200ab2ba 100644
--- a/src/__support/CPP/type_traits/decay.h
+++ b/src/__support/CPP/type_traits/decay.h
@@ -9,7 +9,6 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_DECAY_H
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
#include "src/__support/CPP/type_traits/add_pointer.h"
#include "src/__support/CPP/type_traits/conditional.h"
diff --git a/src/__support/CPP/type_traits/is_constant_evaluated.h b/src/__support/CPP/type_traits/is_constant_evaluated.h
new file mode 100644
index 000000000000..93cfd07b567f
--- /dev/null
+++ b/src/__support/CPP/type_traits/is_constant_evaluated.h
@@ -0,0 +1,21 @@
+//===-- is_constant_evaluated type_traits -----------------------*- 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_CPP_TYPE_TRAITS_IS_CONSTANT_EVALUATED_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_CONSTANT_EVALUATED_H
+
+#include "src/__support/macros/attributes.h"
+
+namespace LIBC_NAMESPACE::cpp {
+
+LIBC_INLINE constexpr bool is_constant_evaluated() {
+ return __builtin_is_constant_evaluated();
+}
+
+} // namespace LIBC_NAMESPACE::cpp
+
+#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_CONSTANT_EVALUATED_H
diff --git a/src/__support/CPP/type_traits/is_destructible.h b/src/__support/CPP/type_traits/is_destructible.h
index d47de1cc797b..f94fe309ac8f 100644
--- a/src/__support/CPP/type_traits/is_destructible.h
+++ b/src/__support/CPP/type_traits/is_destructible.h
@@ -16,12 +16,11 @@
#include "src/__support/CPP/type_traits/true_type.h"
#include "src/__support/CPP/type_traits/type_identity.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_destructible
-#if LIBC_HAS_BUILTIN(__is_destructible)
+#if __has_builtin(__is_destructible)
template <typename T>
struct is_destructible : bool_constant<__is_destructible(T)> {};
#else
diff --git a/src/__support/CPP/type_traits/is_fixed_point.h b/src/__support/CPP/type_traits/is_fixed_point.h
new file mode 100644
index 000000000000..025268bc2979
--- /dev/null
+++ b/src/__support/CPP/type_traits/is_fixed_point.h
@@ -0,0 +1,46 @@
+//===-- is_fixed_point type_traits ------------------------------*- 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_CPP_TYPE_TRAITS_IS_FIXED_POINT_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_FIXED_POINT_H
+
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/macros/attributes.h"
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE::cpp {
+
+// is_fixed_point
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+template <typename T> struct is_fixed_point {
+private:
+ template <typename Head, typename... Args>
+ LIBC_INLINE static constexpr bool __is_unqualified_any_of() {
+ return (... || is_same_v<remove_cv_t<Head>, Args>);
+ }
+
+public:
+ LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of<
+ T, short fract, fract, long fract, unsigned short fract, unsigned fract,
+ unsigned long fract, short accum, accum, long accum, unsigned short accum,
+ unsigned accum, unsigned long accum, short sat fract, sat fract,
+ long sat fract, unsigned short sat fract, unsigned sat fract,
+ unsigned long sat fract, short sat accum, sat accum, long sat accum,
+ unsigned short sat accum, unsigned sat accum, unsigned long sat accum>();
+};
+#else
+template <typename T> struct is_fixed_point : false_type {};
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_fixed_point_v = is_fixed_point<T>::value;
+
+} // namespace LIBC_NAMESPACE::cpp
+
+#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_FIXED_POINT_H
diff --git a/src/__support/CPP/type_traits/is_floating_point.h b/src/__support/CPP/type_traits/is_floating_point.h
index 3a5260bcab11..4c8f50f4e91f 100644
--- a/src/__support/CPP/type_traits/is_floating_point.h
+++ b/src/__support/CPP/type_traits/is_floating_point.h
@@ -11,7 +11,7 @@
#include "src/__support/CPP/type_traits/is_same.h"
#include "src/__support/CPP/type_traits/remove_cv.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128
namespace LIBC_NAMESPACE::cpp {
@@ -24,13 +24,13 @@ private:
}
public:
-#if defined(LIBC_COMPILER_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_FLOAT128)
LIBC_INLINE_VAR static constexpr bool value =
__is_unqualified_any_of<T, float, double, long double, float128>();
#else
LIBC_INLINE_VAR static constexpr bool value =
__is_unqualified_any_of<T, float, double, long double>();
-#endif // LIBC_COMPILER_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_FLOAT128
};
template <typename T>
LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/src/__support/CPP/type_traits/is_function.h b/src/__support/CPP/type_traits/is_function.h
index 557b3224484b..0eba5860ad60 100644
--- a/src/__support/CPP/type_traits/is_function.h
+++ b/src/__support/CPP/type_traits/is_function.h
@@ -12,12 +12,11 @@
#include "src/__support/CPP/type_traits/is_const.h"
#include "src/__support/CPP/type_traits/is_reference.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_function
-#if LIBC_HAS_BUILTIN(__is_function)
+#if __has_builtin(__is_function)
template <typename T>
struct is_function : integral_constant<bool, __is_function(T)> {};
#else
diff --git a/src/__support/CPP/type_traits/is_integral.h b/src/__support/CPP/type_traits/is_integral.h
index 2808be594b20..68e16ff84183 100644
--- a/src/__support/CPP/type_traits/is_integral.h
+++ b/src/__support/CPP/type_traits/is_integral.h
@@ -11,6 +11,7 @@
#include "src/__support/CPP/type_traits/is_same.h"
#include "src/__support/CPP/type_traits/remove_cv.h"
#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
namespace LIBC_NAMESPACE::cpp {
@@ -25,7 +26,7 @@ private:
public:
LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of<
T,
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
__int128_t, __uint128_t,
#endif
char, signed char, unsigned char, short, unsigned short, int,
diff --git a/src/__support/CPP/type_traits/is_lvalue_reference.h b/src/__support/CPP/type_traits/is_lvalue_reference.h
index f52e303afad2..1dff57f186a3 100644
--- a/src/__support/CPP/type_traits/is_lvalue_reference.h
+++ b/src/__support/CPP/type_traits/is_lvalue_reference.h
@@ -12,12 +12,11 @@
#include "src/__support/CPP/type_traits/false_type.h"
#include "src/__support/CPP/type_traits/true_type.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_lvalue_reference
-#if LIBC_HAS_BUILTIN(__is_lvalue_reference)
+#if __has_builtin(__is_lvalue_reference)
template <typename T>
struct is_lvalue_reference : bool_constant<__is_lvalue_reference(T)> {};
#else
diff --git a/src/__support/CPP/type_traits/is_reference.h b/src/__support/CPP/type_traits/is_reference.h
index c017028edf41..bbfb2b7359c3 100644
--- a/src/__support/CPP/type_traits/is_reference.h
+++ b/src/__support/CPP/type_traits/is_reference.h
@@ -12,12 +12,11 @@
#include "src/__support/CPP/type_traits/false_type.h"
#include "src/__support/CPP/type_traits/true_type.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_reference
-#if LIBC_HAS_BUILTIN(__is_reference)
+#if __has_builtin(__is_reference)
template <typename T> struct is_reference : bool_constant<__is_reference(T)> {};
#else
template <typename T> struct is_reference : public false_type {};
diff --git a/src/__support/CPP/type_traits/is_rvalue_reference.h b/src/__support/CPP/type_traits/is_rvalue_reference.h
index f0487e41c998..3efbbe6b033a 100644
--- a/src/__support/CPP/type_traits/is_rvalue_reference.h
+++ b/src/__support/CPP/type_traits/is_rvalue_reference.h
@@ -12,12 +12,11 @@
#include "src/__support/CPP/type_traits/false_type.h"
#include "src/__support/CPP/type_traits/true_type.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_rvalue_reference
-#if LIBC_HAS_BUILTIN(__is_rvalue_reference)
+#if __has_builtin(__is_rvalue_reference)
template <typename T>
struct is_rvalue_reference : bool_constant<__is_rvalue_reference(T)> {};
#else
diff --git a/src/__support/CPP/type_traits/is_trivially_copyable.h b/src/__support/CPP/type_traits/is_trivially_copyable.h
index 0c3fdcc711d5..b4c825d57961 100644
--- a/src/__support/CPP/type_traits/is_trivially_copyable.h
+++ b/src/__support/CPP/type_traits/is_trivially_copyable.h
@@ -9,7 +9,6 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
#include "src/__support/CPP/type_traits/integral_constant.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
diff --git a/src/__support/CPP/type_traits/is_trivially_destructible.h b/src/__support/CPP/type_traits/is_trivially_destructible.h
index 3345149433af..37e0e869266e 100644
--- a/src/__support/CPP/type_traits/is_trivially_destructible.h
+++ b/src/__support/CPP/type_traits/is_trivially_destructible.h
@@ -11,12 +11,11 @@
#include "src/__support/CPP/type_traits/bool_constant.h"
#include "src/__support/CPP/type_traits/is_destructible.h"
#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE::cpp {
// is_trivially_destructible
-#if LIBC_HAS_BUILTIN(__is_trivially_destructible)
+#if __has_builtin(__is_trivially_destructible)
template <typename T>
struct is_trivially_destructible
: public bool_constant<__is_trivially_destructible(T)> {};
@@ -25,7 +24,7 @@ template <typename T>
struct is_trivially_destructible
: public bool_constant<cpp::is_destructible_v<T> &&__has_trivial_destructor(
T)> {};
-#endif // LIBC_HAS_BUILTIN(__is_trivially_destructible)
+#endif // __has_builtin(__is_trivially_destructible)
template <typename T>
LIBC_INLINE_VAR constexpr bool is_trivially_destructible_v =
is_trivially_destructible<T>::value;
diff --git a/src/__support/CPP/type_traits/make_signed.h b/src/__support/CPP/type_traits/make_signed.h
index 21302850bfd4..4652d8b6bfa5 100644
--- a/src/__support/CPP/type_traits/make_signed.h
+++ b/src/__support/CPP/type_traits/make_signed.h
@@ -9,6 +9,7 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_MAKE_SIGNED_H
#include "src/__support/CPP/type_traits/type_identity.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
namespace LIBC_NAMESPACE::cpp {
@@ -26,7 +27,7 @@ template <> struct make_signed<unsigned int> : type_identity<int> {};
template <> struct make_signed<unsigned long> : type_identity<long> {};
template <>
struct make_signed<unsigned long long> : type_identity<long long> {};
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
template <> struct make_signed<__int128_t> : type_identity<__int128_t> {};
template <> struct make_signed<__uint128_t> : type_identity<__int128_t> {};
#endif
diff --git a/src/__support/CPP/type_traits/make_unsigned.h b/src/__support/CPP/type_traits/make_unsigned.h
index 20948014a665..1e814ae002a7 100644
--- a/src/__support/CPP/type_traits/make_unsigned.h
+++ b/src/__support/CPP/type_traits/make_unsigned.h
@@ -9,6 +9,7 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_MAKE_UNSIGNED_H
#include "src/__support/CPP/type_traits/type_identity.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
namespace LIBC_NAMESPACE::cpp {
@@ -31,7 +32,7 @@ template <>
struct make_unsigned<unsigned long> : type_identity<unsigned long> {};
template <>
struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
template <> struct make_unsigned<__int128_t> : type_identity<__uint128_t> {};
template <> struct make_unsigned<__uint128_t> : type_identity<__uint128_t> {};
#endif
diff --git a/src/__support/CPP/type_traits/remove_all_extents.h b/src/__support/CPP/type_traits/remove_all_extents.h
index bff6341d3e45..5941b82bbc16 100644
--- a/src/__support/CPP/type_traits/remove_all_extents.h
+++ b/src/__support/CPP/type_traits/remove_all_extents.h
@@ -9,14 +9,13 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
#include "src/__support/CPP/type_traits/type_identity.h"
-#include "src/__support/macros/config.h"
#include <stddef.h> // size_t
namespace LIBC_NAMESPACE::cpp {
// remove_all_extents
-#if LIBC_HAS_BUILTIN(__remove_all_extents)
+#if __has_builtin(__remove_all_extents)
template <typename T> using remove_all_extents_t = __remove_all_extents(T);
template <typename T>
struct remove_all_extents : cpp::type_identity<remove_all_extents_t<T>> {};
diff --git a/src/__support/FPUtil/BasicOperations.h b/src/__support/FPUtil/BasicOperations.h
index ccc61a89c5f8..6e4156497618 100644
--- a/src/__support/FPUtil/BasicOperations.h
+++ b/src/__support/FPUtil/BasicOperations.h
@@ -9,55 +9,157 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_BASICOPERATIONS_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_BASICOPERATIONS_H
+#include "FEnvImpl.h"
#include "FPBits.h"
+#include "FEnvImpl.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/UInt128.h"
#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
namespace LIBC_NAMESPACE {
namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T abs(T x) {
- FPBits<T> bits(x);
- bits.set_sign(Sign::POS);
- return bits.get_val();
+ return FPBits<T>(x).abs().get_val();
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmin(T x, T y) {
const FPBits<T> bitx(x), bity(y);
- if (bitx.is_nan()) {
+ if (bitx.is_nan())
return y;
- } else if (bity.is_nan()) {
+ if (bity.is_nan())
return x;
- } else if (bitx.sign() != bity.sign()) {
+ if (bitx.sign() != bity.sign())
// To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and
// y has different signs and both are not NaNs, we return the number
// with negative sign.
- return (bitx.is_neg()) ? x : y;
- } else {
- return (x < y ? x : y);
- }
+ return bitx.is_neg() ? x : y;
+ return x < y ? x : y;
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmax(T x, T y) {
FPBits<T> bitx(x), bity(y);
- if (bitx.is_nan()) {
+ if (bitx.is_nan())
return y;
- } else if (bity.is_nan()) {
+ if (bity.is_nan())
return x;
- } else if (bitx.sign() != bity.sign()) {
+ if (bitx.sign() != bity.sign())
// To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and
// y has different signs and both are not NaNs, we return the number
// with positive sign.
+ return bitx.is_neg() ? y : x;
+ return x > y ? x : y;
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fmaximum(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+
+ if (bitx.is_nan())
+ return x;
+ if (bity.is_nan())
+ return y;
+ if (bitx.sign() != bity.sign())
+ return (bitx.is_neg() ? y : x);
+ return x > y ? x : y;
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fminimum(T x, T y) {
+ const FPBits<T> bitx(x), bity(y);
+
+ if (bitx.is_nan())
+ return x;
+ if (bity.is_nan())
+ return y;
+ if (bitx.sign() != bity.sign())
+ return (bitx.is_neg()) ? x : y;
+ return x < y ? x : y;
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fmaximum_num(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+ if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ if (bitx.is_nan() && bity.is_nan())
+ return FPBits<T>::quiet_nan().get_val();
+ }
+ if (bitx.is_nan())
+ return y;
+ if (bity.is_nan())
+ return x;
+ if (bitx.sign() != bity.sign())
return (bitx.is_neg() ? y : x);
- } else {
- return (x > y ? x : y);
+ return x > y ? x : y;
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fminimum_num(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+ if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ if (bitx.is_nan() && bity.is_nan())
+ return FPBits<T>::quiet_nan().get_val();
}
+ if (bitx.is_nan())
+ return y;
+ if (bity.is_nan())
+ return x;
+ if (bitx.sign() != bity.sign())
+ return (bitx.is_neg() ? x : y);
+ return x < y ? x : y;
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fmaximum_mag(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+
+ if (abs(x) > abs(y))
+ return x;
+ if (abs(y) > abs(x))
+ return y;
+ return fmaximum(x, y);
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fminimum_mag(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+
+ if (abs(x) < abs(y))
+ return x;
+ if (abs(y) < abs(x))
+ return y;
+ return fminimum(x, y);
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fmaximum_mag_num(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+
+ if (abs(x) > abs(y))
+ return x;
+ if (abs(y) > abs(x))
+ return y;
+ return fmaximum_num(x, y);
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T fminimum_mag_num(T x, T y) {
+ FPBits<T> bitx(x), bity(y);
+
+ if (abs(x) < abs(y))
+ return x;
+ if (abs(y) < abs(x))
+ return y;
+ return fminimum_num(x, y);
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
@@ -75,6 +177,69 @@ LIBC_INLINE T fdim(T x, T y) {
return (x > y ? x - y : 0);
}
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE int canonicalize(T &cx, const T &x) {
+ FPBits<T> sx(x);
+ if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
+ // All the pseudo and unnormal numbers are not canonical.
+ // More precisely :
+ // Exponent | Significand | Meaning
+ // | Bits 63-62 | Bits 61-0 |
+ // All Ones | 00 | Zero | Pseudo Infinity, Value = SNaN
+ // All Ones | 00 | Non-Zero | Pseudo NaN, Value = SNaN
+ // All Ones | 01 | Anything | Pseudo NaN, Value = SNaN
+ // | Bit 63 | Bits 62-0 |
+ // All zeroes | One | Anything | Pseudo Denormal, Value =
+ // | | | (−1)**s × m × 2**−16382
+ // All Other | Zero | Anything | Unnormal, Value = SNaN
+ // Values | | |
+ bool bit63 = sx.get_implicit_bit();
+ UInt128 mantissa = sx.get_explicit_mantissa();
+ bool bit62 = static_cast<bool>((mantissa & (1ULL << 62)) >> 62);
+ int exponent = sx.get_biased_exponent();
+ if (exponent == 0x7FFF) {
+ if (!bit63 && !bit62) {
+ if (mantissa == 0) {
+ cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ }
+ cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else if (!bit63 && bit62) {
+ cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
+ cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa())
+ .get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else
+ cx = x;
+ } else if (exponent == 0 && bit63)
+ cx = FPBits<T>::make_value(mantissa, 0).get_val();
+ else if (exponent != 0 && !bit63) {
+ cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
+ cx =
+ FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else
+ cx = x;
+ } else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
+ cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
+ raise_except_if_required(FE_INVALID);
+ return 1;
+ } else
+ cx = x;
+ return 0;
+}
+
} // namespace fputil
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/FPUtil/FEnvImpl.h b/src/__support/FPUtil/FEnvImpl.h
index 6810659733de..6086d5d3de2d 100644
--- a/src/__support/FPUtil/FEnvImpl.h
+++ b/src/__support/FPUtil/FEnvImpl.h
@@ -9,13 +9,11 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
#include "src/__support/macros/properties/architectures.h"
#include "src/errno/libc_errno.h"
-
#include <fenv.h>
-#include <math.h>
#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
#if defined(__APPLE__)
diff --git a/src/__support/FPUtil/FPBits.h b/src/__support/FPUtil/FPBits.h
index d975638be348..155bff2f5581 100644
--- a/src/__support/FPUtil/FPBits.h
+++ b/src/__support/FPUtil/FPBits.h
@@ -13,9 +13,11 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/UInt128.h"
#include "src/__support/common.h"
+#include "src/__support/libc_assert.h" // LIBC_ASSERT
#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
-#include "src/__support/macros/properties/float.h" // LIBC_COMPILER_HAS_FLOAT128
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128
#include "src/__support/math_extras.h" // mask_trailing_ones
+#include "src/__support/sign.h" // Sign
#include <stdint.h>
@@ -31,32 +33,6 @@ enum class FPType {
X86_Binary80,
};
-// A type to interact with floating point type signs.
-// This may be moved outside of 'fputil' if useful.
-struct Sign {
- LIBC_INLINE constexpr bool is_pos() const { return !is_negative; }
- LIBC_INLINE constexpr bool is_neg() const { return is_negative; }
-
- LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) {
- return a.is_negative == b.is_negative;
- }
- LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) {
- return !(a == b);
- }
-
- static const Sign POS;
- static const Sign NEG;
-
-private:
- LIBC_INLINE constexpr explicit Sign(bool is_negative)
- : is_negative(is_negative) {}
-
- bool is_negative;
-};
-
-LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true);
-LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false);
-
// The classes hierarchy is as follows:
//
// ┌───────────────────┐
@@ -75,27 +51,32 @@ LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false);
// │ │
// └────────────┬─────────────┘
// │
-// ┌─────┴─────┐
-// │ FPRep<T> │
-// └───────────┘
+// ┌───────┴───────┐
+// │ FPRepImpl<T> │
+// └───────▲───────┘
// │
-// ┌─────┴─────┐
-// │ FPBits<T> │
-// └───────────┘
+// ┌────────┴────────┐
+// ┌─────┴─────┐ ┌─────┴─────┐
+// │ FPRep<T> │ │ FPBits<T> │
+// └───────────┘ └───────────┘
//
// - 'FPLayout' defines only a few constants, namely the 'StorageType' and
-// length of the sign, the exponent, fraction and significand parts.
+// length of the sign, the exponent, fraction and significand parts.
// - 'FPStorage' builds more constants on top of those from 'FPLayout' like
-// exponent bias and masks. It also holds the bit representation of the
-// floating point as a 'StorageType' type and defines tools to assemble or test
-// these parts.
+// exponent bias and masks. It also holds the bit representation of the
+// floating point as a 'StorageType' type and defines tools to assemble or
+// test these parts.
// - 'FPRepSem' defines functions to interact semantically with the floating
-// point representation. The default implementation is the one for 'IEEE754', a
-// specialization is provided for X86 Extended Precision.
-// - 'FPRep' derives from 'FPRepSem' and adds functions that are common to all
-// implementations.
-// - 'FPBits' exposes all functions from 'FPRep' but operates on the native C++
-// floating point type instead of 'FPType'.
+// point representation. The default implementation is the one for 'IEEE754',
+// a specialization is provided for X86 Extended Precision.
+// - 'FPRepImpl' derives from 'FPRepSem' and adds functions that are common to
+// all implementations or build on the ones in 'FPRepSem'.
+// - 'FPRep' exposes all functions from 'FPRepImpl' and returns 'FPRep'
+// instances when using Builders (static functions to create values).
+// - 'FPBits' exposes all the functions from 'FPRepImpl' but operates on the
+// native C++ floating point type instead of 'FPType'. An additional 'get_val'
+// function allows getting the C++ floating point type value back. Builders
+// called from 'FPBits' return 'FPBits' instances.
namespace internal {
@@ -197,12 +178,22 @@ template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
static_assert((SIG_MASK | EXP_MASK | SIGN_MASK) == FP_MASK, "masks cover");
protected:
+ // Merge bits from 'a' and 'b' values according to 'mask'.
+ // Use 'a' bits when corresponding 'mask' bits are zeroes and 'b' bits when
+ // corresponding bits are ones.
+ LIBC_INLINE static constexpr StorageType merge(StorageType a, StorageType b,
+ StorageType mask) {
+ // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
+ return a ^ ((a ^ b) & mask);
+ }
+
// A stongly typed integer that prevents mixing and matching integers with
// different semantics.
template <typename T> struct TypedInt {
using value_type = T;
LIBC_INLINE constexpr explicit TypedInt(T value) : value(value) {}
LIBC_INLINE constexpr TypedInt(const TypedInt &value) = default;
+ LIBC_INLINE constexpr TypedInt &operator=(const TypedInt &value) = default;
LIBC_INLINE constexpr explicit operator T() const { return value; }
@@ -210,47 +201,66 @@ protected:
return StorageType(value);
}
- private:
+ LIBC_INLINE friend constexpr bool operator==(TypedInt a, TypedInt b) {
+ return a.value == b.value;
+ }
+ LIBC_INLINE friend constexpr bool operator!=(TypedInt a, TypedInt b) {
+ return a.value != b.value;
+ }
+
+ protected:
T value;
};
// An opaque type to store a floating point exponent.
// We define special values but it is valid to create arbitrary values as long
- // as they are in the range [MIN, MAX].
+ // as they are in the range [min, max].
struct Exponent : public TypedInt<int32_t> {
using UP = TypedInt<int32_t>;
using UP::UP;
- LIBC_INLINE
- static constexpr auto MIN() { return Exponent(1 - EXP_BIAS); }
- LIBC_INLINE static constexpr auto ZERO() { return Exponent(0); }
- LIBC_INLINE static constexpr auto MAX() { return Exponent(EXP_BIAS); }
+ LIBC_INLINE static constexpr auto subnormal() {
+ return Exponent(-EXP_BIAS);
+ }
+ LIBC_INLINE static constexpr auto min() { return Exponent(1 - EXP_BIAS); }
+ LIBC_INLINE static constexpr auto zero() { return Exponent(0); }
+ LIBC_INLINE static constexpr auto max() { return Exponent(EXP_BIAS); }
+ LIBC_INLINE static constexpr auto inf() { return Exponent(EXP_BIAS + 1); }
};
// An opaque type to store a floating point biased exponent.
// We define special values but it is valid to create arbitrary values as long
- // as they are in the range [BITS_ALL_ZEROES, BITS_ALL_ONES].
- // Values greater than BITS_ALL_ONES are truncated.
+ // as they are in the range [zero, bits_all_ones].
+ // Values greater than bits_all_ones are truncated.
struct BiasedExponent : public TypedInt<uint32_t> {
using UP = TypedInt<uint32_t>;
using UP::UP;
LIBC_INLINE constexpr BiasedExponent(Exponent exp)
: UP(static_cast<int32_t>(exp) + EXP_BIAS) {}
- // The exponent value for denormal numbers.
- LIBC_INLINE static constexpr auto BITS_ALL_ZEROES() {
- return BiasedExponent(uint32_t(0));
+
+ // Cast operator to get convert from BiasedExponent to Exponent.
+ LIBC_INLINE constexpr operator Exponent() const {
+ return Exponent(UP::value - EXP_BIAS);
}
- // The exponent value for infinity.
- LIBC_INLINE static constexpr auto BITS_ALL_ONES() {
- return BiasedExponent(uint32_t(2 * EXP_BIAS + 1));
+
+ LIBC_INLINE constexpr BiasedExponent &operator++() {
+ LIBC_ASSERT(*this != BiasedExponent(Exponent::inf()));
+ ++UP::value;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr BiasedExponent &operator--() {
+ LIBC_ASSERT(*this != BiasedExponent(Exponent::subnormal()));
+ --UP::value;
+ return *this;
}
};
// An opaque type to store a floating point significand.
// We define special values but it is valid to create arbitrary values as long
- // as they are in the range [ZERO, BITS_ALL_ONES].
+ // as they are in the range [zero, bits_all_ones].
// Note that the semantics of the Significand are implementation dependent.
- // Values greater than BITS_ALL_ONES are truncated.
+ // Values greater than bits_all_ones are truncated.
struct Significand : public TypedInt<StorageType> {
using UP = TypedInt<StorageType>;
using UP::UP;
@@ -270,16 +280,16 @@ protected:
return Significand(StorageType(a.to_storage_type() >> shift));
}
- LIBC_INLINE static constexpr auto ZERO() {
+ LIBC_INLINE static constexpr auto zero() {
return Significand(StorageType(0));
}
- LIBC_INLINE static constexpr auto LSB() {
+ LIBC_INLINE static constexpr auto lsb() {
return Significand(StorageType(1));
}
- LIBC_INLINE static constexpr auto MSB() {
+ LIBC_INLINE static constexpr auto msb() {
return Significand(StorageType(1) << (SIG_LEN - 1));
}
- LIBC_INLINE static constexpr auto BITS_ALL_ONES() {
+ LIBC_INLINE static constexpr auto bits_all_ones() {
return Significand(SIG_MASK);
}
};
@@ -316,6 +326,23 @@ protected:
LIBC_INLINE constexpr StorageType exp_sig_bits() const {
return bits & EXP_SIG_MASK;
}
+
+ // Parts
+ LIBC_INLINE constexpr BiasedExponent biased_exponent() const {
+ return BiasedExponent(static_cast<uint32_t>(exp_bits() >> SIG_LEN));
+ }
+ LIBC_INLINE constexpr void set_biased_exponent(BiasedExponent biased) {
+ bits = merge(bits, encode(biased), EXP_MASK);
+ }
+
+public:
+ LIBC_INLINE constexpr Sign sign() const {
+ return (bits & SIGN_MASK) ? Sign::NEG : Sign::POS;
+ }
+ LIBC_INLINE constexpr void set_sign(Sign signVal) {
+ if (sign() != signVal)
+ bits ^= SIGN_MASK;
+ }
};
// This layer defines all functions that are specific to how the the floating
@@ -329,9 +356,9 @@ struct FPRepSem : public FPStorage<fp_type> {
using UP::FRACTION_MASK;
protected:
- using BiasedExp = typename UP::BiasedExponent;
- using Exp = typename UP::Exponent;
- using Sig = typename UP::Significand;
+ using typename UP::Exponent;
+ using typename UP::Significand;
+ using UP::bits;
using UP::encode;
using UP::exp_bits;
using UP::exp_sig_bits;
@@ -340,61 +367,72 @@ protected:
public:
// Builders
+ LIBC_INLINE static constexpr RetT zero(Sign sign = Sign::POS) {
+ return RetT(encode(sign, Exponent::subnormal(), Significand::zero()));
+ }
LIBC_INLINE static constexpr RetT one(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exp::ZERO(), Sig::ZERO()));
+ return RetT(encode(sign, Exponent::zero(), Significand::zero()));
}
LIBC_INLINE static constexpr RetT min_subnormal(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ZEROES(), Sig::LSB()));
+ return RetT(encode(sign, Exponent::subnormal(), Significand::lsb()));
}
LIBC_INLINE static constexpr RetT max_subnormal(Sign sign = Sign::POS) {
return RetT(
- encode(sign, BiasedExp::BITS_ALL_ZEROES(), Sig::BITS_ALL_ONES()));
+ encode(sign, Exponent::subnormal(), Significand::bits_all_ones()));
}
LIBC_INLINE static constexpr RetT min_normal(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exp::MIN(), Sig::ZERO()));
+ return RetT(encode(sign, Exponent::min(), Significand::zero()));
}
LIBC_INLINE static constexpr RetT max_normal(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exp::MAX(), Sig::BITS_ALL_ONES()));
+ return RetT(encode(sign, Exponent::max(), Significand::bits_all_ones()));
}
LIBC_INLINE static constexpr RetT inf(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(), Sig::ZERO()));
+ return RetT(encode(sign, Exponent::inf(), Significand::zero()));
}
LIBC_INLINE static constexpr RetT signaling_nan(Sign sign = Sign::POS,
StorageType v = 0) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(),
- (v ? Sig(v) : (Sig::MSB() >> 1))));
+ return RetT(encode(sign, Exponent::inf(),
+ (v ? Significand(v) : (Significand::msb() >> 1))));
}
LIBC_INLINE static constexpr RetT quiet_nan(Sign sign = Sign::POS,
StorageType v = 0) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(), Sig::MSB() | Sig(v)));
+ return RetT(
+ encode(sign, Exponent::inf(), Significand::msb() | Significand(v)));
}
// Observers
+ LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
LIBC_INLINE constexpr bool is_nan() const {
- return exp_sig_bits() > encode(BiasedExp::BITS_ALL_ONES(), Sig::ZERO());
+ return exp_sig_bits() > encode(Exponent::inf(), Significand::zero());
}
LIBC_INLINE constexpr bool is_quiet_nan() const {
- return exp_sig_bits() >= encode(BiasedExp::BITS_ALL_ONES(), Sig::MSB());
+ return exp_sig_bits() >= encode(Exponent::inf(), Significand::msb());
}
LIBC_INLINE constexpr bool is_signaling_nan() const {
return is_nan() && !is_quiet_nan();
}
LIBC_INLINE constexpr bool is_inf() const {
- return exp_sig_bits() == encode(BiasedExp::BITS_ALL_ONES(), Sig::ZERO());
+ return exp_sig_bits() == encode(Exponent::inf(), Significand::zero());
}
LIBC_INLINE constexpr bool is_finite() const {
- return exp_bits() != encode(BiasedExp::BITS_ALL_ONES());
+ return exp_bits() != encode(Exponent::inf());
}
LIBC_INLINE
constexpr bool is_subnormal() const {
- return exp_bits() == encode(BiasedExp::BITS_ALL_ZEROES());
+ return exp_bits() == encode(Exponent::subnormal());
}
LIBC_INLINE constexpr bool is_normal() const {
return is_finite() && !is_subnormal();
}
+ LIBC_INLINE constexpr RetT next_toward_inf() const {
+ if (is_finite())
+ return RetT(bits + StorageType(1));
+ return RetT(bits);
+ }
+
// Returns the mantissa with the implicit bit set iff the current
// value is a valid normal number.
- LIBC_INLINE constexpr StorageType get_explicit_mantissa() {
+ LIBC_INLINE constexpr StorageType get_explicit_mantissa() const {
if (is_subnormal())
return sig_bits();
return (StorageType(1) << UP::SIG_LEN) | sig_bits();
@@ -422,44 +460,50 @@ struct FPRepSem<FPType::X86_Binary80, RetT>
"whole significand");
protected:
- using BiasedExp = typename UP::BiasedExponent;
- using Sig = typename UP::Significand;
+ using typename UP::Exponent;
+ using typename UP::Significand;
using UP::encode;
using UP::UP;
public:
// Builders
+ LIBC_INLINE static constexpr RetT zero(Sign sign = Sign::POS) {
+ return RetT(encode(sign, Exponent::subnormal(), Significand::zero()));
+ }
LIBC_INLINE static constexpr RetT one(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exponent::ZERO(), Sig::MSB()));
+ return RetT(encode(sign, Exponent::zero(), Significand::msb()));
}
LIBC_INLINE static constexpr RetT min_subnormal(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ZEROES(), Sig::LSB()));
+ return RetT(encode(sign, Exponent::subnormal(), Significand::lsb()));
}
LIBC_INLINE static constexpr RetT max_subnormal(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ZEROES(),
- Sig::BITS_ALL_ONES() ^ Sig::MSB()));
+ return RetT(encode(sign, Exponent::subnormal(),
+ Significand::bits_all_ones() ^ Significand::msb()));
}
LIBC_INLINE static constexpr RetT min_normal(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exponent::MIN(), Sig::MSB()));
+ return RetT(encode(sign, Exponent::min(), Significand::msb()));
}
LIBC_INLINE static constexpr RetT max_normal(Sign sign = Sign::POS) {
- return RetT(encode(sign, Exponent::MAX(), Sig::BITS_ALL_ONES()));
+ return RetT(encode(sign, Exponent::max(), Significand::bits_all_ones()));
}
LIBC_INLINE static constexpr RetT inf(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(), Sig::MSB()));
+ return RetT(encode(sign, Exponent::inf(), Significand::msb()));
}
LIBC_INLINE static constexpr RetT signaling_nan(Sign sign = Sign::POS,
StorageType v = 0) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(),
- Sig::MSB() | (v ? Sig(v) : (Sig::MSB() >> 2))));
+ return RetT(encode(sign, Exponent::inf(),
+ Significand::msb() |
+ (v ? Significand(v) : (Significand::msb() >> 2))));
}
LIBC_INLINE static constexpr RetT quiet_nan(Sign sign = Sign::POS,
StorageType v = 0) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ONES(),
- Sig::MSB() | (Sig::MSB() >> 1) | Sig(v)));
+ return RetT(encode(sign, Exponent::inf(),
+ Significand::msb() | (Significand::msb() >> 1) |
+ Significand(v)));
}
// Observers
+ LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
LIBC_INLINE constexpr bool is_nan() const {
// Most encoding forms from the table found in
// https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format
@@ -472,36 +516,51 @@ public:
// - Quiet Not a Number
// - Unnormal
// This can be reduced to the following logic:
- if (exp_bits() == encode(BiasedExp::BITS_ALL_ONES()))
+ if (exp_bits() == encode(Exponent::inf()))
return !is_inf();
- if (exp_bits() != encode(BiasedExp::BITS_ALL_ZEROES()))
- return (sig_bits() & encode(Sig::MSB())) == 0;
+ if (exp_bits() != encode(Exponent::subnormal()))
+ return (sig_bits() & encode(Significand::msb())) == 0;
return false;
}
LIBC_INLINE constexpr bool is_quiet_nan() const {
return exp_sig_bits() >=
- encode(BiasedExp::BITS_ALL_ONES(), Sig::MSB() | (Sig::MSB() >> 1));
+ encode(Exponent::inf(),
+ Significand::msb() | (Significand::msb() >> 1));
}
LIBC_INLINE constexpr bool is_signaling_nan() const {
return is_nan() && !is_quiet_nan();
}
LIBC_INLINE constexpr bool is_inf() const {
- return exp_sig_bits() == encode(BiasedExp::BITS_ALL_ONES(), Sig::MSB());
+ return exp_sig_bits() == encode(Exponent::inf(), Significand::msb());
}
LIBC_INLINE constexpr bool is_finite() const {
return !is_inf() && !is_nan();
}
LIBC_INLINE
constexpr bool is_subnormal() const {
- return exp_bits() == encode(BiasedExp::BITS_ALL_ZEROES());
+ return exp_bits() == encode(Exponent::subnormal());
}
LIBC_INLINE constexpr bool is_normal() const {
const auto exp = exp_bits();
- if (exp == encode(BiasedExp::BITS_ALL_ZEROES()) ||
- exp == encode(BiasedExp::BITS_ALL_ONES()))
+ if (exp == encode(Exponent::subnormal()) || exp == encode(Exponent::inf()))
return false;
return get_implicit_bit();
}
+ LIBC_INLINE constexpr RetT next_toward_inf() const {
+ if (is_finite()) {
+ if (exp_sig_bits() == max_normal().uintval()) {
+ return inf(sign());
+ } else if (exp_sig_bits() == max_subnormal().uintval()) {
+ return min_normal(sign());
+ } else if (sig_bits() == SIG_MASK) {
+ return RetT(encode(sign(), ++biased_exponent(), Significand::zero()));
+ } else {
+ return RetT(bits + StorageType(1));
+ }
+ }
+ return RetT(bits);
+ }
+
LIBC_INLINE constexpr StorageType get_explicit_mantissa() const {
return sig_bits();
}
@@ -520,21 +579,21 @@ public:
}
};
-// 'FPRep' is the bottom of the class hierarchy that only deals with 'FPType'.
-// The operations dealing with specific float semantics are implemented by
-// 'FPRepSem' above and specialized when needed.
+// 'FPRepImpl' is the bottom of the class hierarchy that only deals with
+// 'FPType'. The operations dealing with specific float semantics are
+// implemented by 'FPRepSem' above and specialized when needed.
//
// The 'RetT' type is being propagated up to 'FPRepSem' so that the functions
// creating new values (Builders) can return the appropriate type. That is, when
// creating a value through 'FPBits' below the builder will return an 'FPBits'
-// value:
-// i.e., FPBits<float>::zero() // returns an FPBits<float>
-// When we don't care about specific C++ floating point type we can use 'FPRep'
-// directly and 'RetT' defaults to 'StorageType':
-// i.e., FPRep<FPType:IEEE754_Binary32:>::zero() // returns an 'uint32_t'
-template <FPType fp_type,
- typename RetT = typename FPLayout<fp_type>::StorageType>
-struct FPRep : public FPRepSem<fp_type, RetT> {
+// value.
+// FPBits<float>::zero(); // returns an FPBits<>
+//
+// When we don't care about specific C++ floating point type we can use
+// 'FPRep' and specify the 'FPType' directly.
+// FPRep<FPType::IEEE754_Binary32:>::zero() // returns an FPRep<>
+template <FPType fp_type, typename RetT>
+struct FPRepImpl : public FPRepSem<fp_type, RetT> {
using UP = FPRepSem<fp_type, RetT>;
using StorageType = typename UP::StorageType;
@@ -544,29 +603,32 @@ protected:
using UP::exp_bits;
using UP::exp_sig_bits;
- using BiasedExp = typename UP::BiasedExponent;
- using Sig = typename UP::Significand;
+ using typename UP::BiasedExponent;
+ using typename UP::Exponent;
+ using typename UP::Significand;
using UP::FP_MASK;
- using UP::SIG_LEN;
public:
// Constants.
using UP::EXP_BIAS;
using UP::EXP_MASK;
using UP::FRACTION_MASK;
+ using UP::SIG_LEN;
+ using UP::SIG_MASK;
using UP::SIGN_MASK;
LIBC_INLINE_VAR static constexpr int MAX_BIASED_EXPONENT =
(1 << UP::EXP_LEN) - 1;
- LIBC_INLINE constexpr FPRep() = default;
- LIBC_INLINE constexpr explicit FPRep(StorageType x) : UP(x) {}
+ // CTors
+ LIBC_INLINE constexpr FPRepImpl() = default;
+ LIBC_INLINE constexpr explicit FPRepImpl(StorageType x) : UP(x) {}
// Comparison
- LIBC_INLINE constexpr friend bool operator==(FPRep a, FPRep b) {
+ LIBC_INLINE constexpr friend bool operator==(FPRepImpl a, FPRepImpl b) {
return a.uintval() == b.uintval();
}
- LIBC_INLINE constexpr friend bool operator!=(FPRep a, FPRep b) {
+ LIBC_INLINE constexpr friend bool operator!=(FPRepImpl a, FPRepImpl b) {
return a.uintval() != b.uintval();
}
@@ -577,9 +639,6 @@ public:
}
// Builders
- LIBC_INLINE static constexpr RetT zero(Sign sign = Sign::POS) {
- return RetT(encode(sign, BiasedExp::BITS_ALL_ZEROES(), Sig::ZERO()));
- }
using UP::inf;
using UP::max_normal;
using UP::max_subnormal;
@@ -588,6 +647,7 @@ public:
using UP::one;
using UP::quiet_nan;
using UP::signaling_nan;
+ using UP::zero;
// Modifiers
LIBC_INLINE constexpr RetT abs() const {
@@ -596,8 +656,6 @@ public:
// Observers
using UP::get_explicit_mantissa;
- LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
- LIBC_INLINE constexpr bool is_inf_or_nan() const { return !is_finite(); }
using UP::is_finite;
using UP::is_inf;
using UP::is_nan;
@@ -605,29 +663,23 @@ public:
using UP::is_quiet_nan;
using UP::is_signaling_nan;
using UP::is_subnormal;
+ using UP::is_zero;
+ using UP::next_toward_inf;
+ using UP::sign;
+ LIBC_INLINE constexpr bool is_inf_or_nan() const { return !is_finite(); }
LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); }
LIBC_INLINE constexpr bool is_pos() const { return sign().is_pos(); }
- // Parts
- LIBC_INLINE constexpr Sign sign() const {
- return (bits & SIGN_MASK) ? Sign::NEG : Sign::POS;
- }
-
- LIBC_INLINE constexpr void set_sign(Sign signVal) {
- if (sign() != signVal)
- bits ^= SIGN_MASK;
- }
-
LIBC_INLINE constexpr uint16_t get_biased_exponent() const {
- return uint16_t((bits & UP::EXP_MASK) >> UP::SIG_LEN);
+ return static_cast<uint16_t>(static_cast<uint32_t>(UP::biased_exponent()));
}
LIBC_INLINE constexpr void set_biased_exponent(StorageType biased) {
- bits = merge(bits, biased << SIG_LEN, EXP_MASK);
+ UP::set_biased_exponent(BiasedExponent((int32_t)biased));
}
LIBC_INLINE constexpr int get_exponent() const {
- return int(get_biased_exponent()) - EXP_BIAS;
+ return static_cast<int32_t>(Exponent(UP::biased_exponent()));
}
// If the number is subnormal, the exponent is treated as if it were the
@@ -637,14 +689,12 @@ public:
// will give a slightly incorrect result. Additionally, zero has an exponent
// of zero, and that should actually be treated as zero.
LIBC_INLINE constexpr int get_explicit_exponent() const {
- const int biased_exp = int(get_biased_exponent());
- if (is_zero()) {
- return 0;
- } else if (biased_exp == 0) {
- return 1 - EXP_BIAS;
- } else {
- return biased_exp - EXP_BIAS;
- }
+ Exponent exponent(UP::biased_exponent());
+ if (is_zero())
+ exponent = Exponent::zero();
+ if (exponent == Exponent::subnormal())
+ exponent = Exponent::min();
+ return static_cast<int32_t>(exponent);
}
LIBC_INLINE constexpr StorageType get_mantissa() const {
@@ -652,23 +702,29 @@ public:
}
LIBC_INLINE constexpr void set_mantissa(StorageType mantVal) {
- bits = merge(bits, mantVal, FRACTION_MASK);
+ bits = UP::merge(bits, mantVal, FRACTION_MASK);
}
+ LIBC_INLINE constexpr void set_significand(StorageType sigVal) {
+ bits = UP::merge(bits, sigVal, SIG_MASK);
+ }
// Unsafe function to create a floating point representation.
// It simply packs the sign, biased exponent and mantissa values without
// checking bound nor normalization.
+ //
+ // WARNING: For X86 Extended Precision, implicit bit needs to be set correctly
+ // in the 'mantissa' by the caller. This function will not check for its
+ // validity.
+ //
// FIXME: Use an uint32_t for 'biased_exp'.
LIBC_INLINE static constexpr RetT
create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {
- static_assert(fp_type != FPType::X86_Binary80,
- "This function is not tested for X86 Extended Precision");
- return RetT(encode(sign, BiasedExp(static_cast<uint32_t>(biased_exp)),
- Sig(mantissa)));
+ return RetT(encode(sign, BiasedExponent(static_cast<uint32_t>(biased_exp)),
+ Significand(mantissa)));
}
- // The function converts integer number and unbiased exponent to proper float
- // T type:
+ // The function converts integer number and unbiased exponent to proper
+ // float T type:
// Result = number * 2^(ep+1 - exponent_bias)
// Be careful!
// 1) "ep" is the raw exponent value.
@@ -678,32 +734,34 @@ public:
// 4) "number" zero value is not processed correctly.
// 5) Number is unsigned, so the result can be only positive.
LIBC_INLINE static constexpr RetT make_value(StorageType number, int ep) {
- static_assert(fp_type != FPType::X86_Binary80,
- "This function is not tested for X86 Extended Precision");
- FPRep result;
- // offset: +1 for sign, but -1 for implicit first bit
- int lz = cpp::countl_zero(number) - UP::EXP_LEN;
+ FPRepImpl result(0);
+ int lz =
+ UP::FRACTION_LEN + 1 - (UP::STORAGE_LEN - cpp::countl_zero(number));
+
number <<= lz;
ep -= lz;
if (LIBC_LIKELY(ep >= 0)) {
// Implicit number bit will be removed by mask
- result.set_mantissa(number);
+ result.set_significand(number);
result.set_biased_exponent(ep + 1);
} else {
- result.set_mantissa(number >> -ep);
+ result.set_significand(number >> -ep);
}
return RetT(result.uintval());
}
+};
-private:
- // Merge bits from 'a' and 'b' values according to 'mask'.
- // Use 'a' bits when corresponding 'mask' bits are zeroes and 'b' bits when
- // corresponding bits are ones.
- LIBC_INLINE static constexpr StorageType merge(StorageType a, StorageType b,
- StorageType mask) {
- // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
- return a ^ ((a ^ b) & mask);
+// A generic class to manipulate floating point formats.
+// It derives its functionality to FPRepImpl above.
+template <FPType fp_type>
+struct FPRep : public FPRepImpl<fp_type, FPRep<fp_type>> {
+ using UP = FPRepImpl<fp_type, FPRep<fp_type>>;
+ using StorageType = typename UP::StorageType;
+ using UP::UP;
+
+ LIBC_INLINE constexpr explicit operator StorageType() const {
+ return UP::uintval();
}
};
@@ -724,16 +782,12 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
else if constexpr (__LDBL_MANT_DIG__ == 113)
return FPType::IEEE754_Binary128;
}
-#if defined(LIBC_COMPILER_HAS_C23_FLOAT16)
- else if constexpr (cpp::is_same_v<UnqualT, _Float16>)
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+ else if constexpr (cpp::is_same_v<UnqualT, float16>)
return FPType::IEEE754_Binary16;
#endif
-#if defined(LIBC_COMPILER_HAS_C23_FLOAT128)
- else if constexpr (cpp::is_same_v<UnqualT, _Float128>)
- return FPType::IEEE754_Binary128;
-#endif
-#if defined(LIBC_COMPILER_HAS_FLOAT128_EXTENSION)
- else if constexpr (cpp::is_same_v<UnqualT, __float128>)
+#if defined(LIBC_TYPES_HAS_FLOAT128)
+ else if constexpr (cpp::is_same_v<UnqualT, float128>)
return FPType::IEEE754_Binary128;
#endif
else
@@ -741,12 +795,12 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
}
// A generic class to manipulate C++ floating point formats.
-// It derives most of its functionality to FPRep above.
+// It derives its functionality to FPRepImpl above.
template <typename T>
-struct FPBits final : public internal::FPRep<get_fp_type<T>(), FPBits<T>> {
+struct FPBits final : public internal::FPRepImpl<get_fp_type<T>(), FPBits<T>> {
static_assert(cpp::is_floating_point_v<T>,
"FPBits instantiated with invalid type.");
- using UP = internal::FPRep<get_fp_type<T>(), FPBits<T>>;
+ using UP = internal::FPRepImpl<get_fp_type<T>(), FPBits<T>>;
using StorageType = typename UP::StorageType;
// Constructors.
diff --git a/src/__support/FPUtil/ManipulationFunctions.h b/src/__support/FPUtil/ManipulationFunctions.h
index 9becbaa45ead..2c90b4888c2e 100644
--- a/src/__support/FPUtil/ManipulationFunctions.h
+++ b/src/__support/FPUtil/ManipulationFunctions.h
@@ -12,7 +12,10 @@
#include "FPBits.h"
#include "NearestIntegerOperations.h"
#include "NormalFloat.h"
+#include "dyadic_float.h"
+#include "rounding_mode.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN
#include "src/__support/CPP/type_traits.h"
@@ -20,8 +23,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include <math.h>
-
namespace LIBC_NAMESPACE {
namespace fputil {
@@ -69,58 +70,82 @@ LIBC_INLINE T copysign(T x, T y) {
return xbits.get_val();
}
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int ilogb(T x) {
- // TODO: Raise appropriate floating point exceptions and set errno to the
- // an appropriate error value wherever relevant.
- FPBits<T> bits(x);
- if (bits.is_zero()) {
- return FP_ILOGB0;
- } else if (bits.is_nan()) {
- return FP_ILOGBNAN;
- } else if (bits.is_inf()) {
- return INT_MAX;
+template <typename T> struct IntLogbConstants;
+
+template <> struct IntLogbConstants<int> {
+ LIBC_INLINE_VAR static constexpr int FP_LOGB0 = FP_ILOGB0;
+ LIBC_INLINE_VAR static constexpr int FP_LOGBNAN = FP_ILOGBNAN;
+ LIBC_INLINE_VAR static constexpr int T_MAX = INT_MAX;
+ LIBC_INLINE_VAR static constexpr int T_MIN = INT_MIN;
+};
+
+template <> struct IntLogbConstants<long> {
+ LIBC_INLINE_VAR static constexpr long FP_LOGB0 = FP_ILOGB0;
+ LIBC_INLINE_VAR static constexpr long FP_LOGBNAN = FP_ILOGBNAN;
+ LIBC_INLINE_VAR static constexpr long T_MAX = LONG_MAX;
+ LIBC_INLINE_VAR static constexpr long T_MIN = LONG_MIN;
+};
+
+template <typename T, typename U>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<U>, T>
+intlogb(U x) {
+ FPBits<U> bits(x);
+ if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
+ set_errno_if_required(EDOM);
+ raise_except_if_required(FE_INVALID);
+
+ if (bits.is_zero())
+ return IntLogbConstants<T>::FP_LOGB0;
+ if (bits.is_nan())
+ return IntLogbConstants<T>::FP_LOGBNAN;
+ // bits is inf.
+ return IntLogbConstants<T>::T_MAX;
}
- NormalFloat<T> normal(bits);
+ DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
+ int exponent = normal.get_unbiased_exponent();
// The C standard does not specify the return value when an exponent is
// out of int range. However, XSI conformance required that INT_MAX or
// INT_MIN are returned.
// NOTE: It is highly unlikely that exponent will be out of int range as
// the exponent is only 15 bits wide even for the 128-bit floating point
// format.
- if (normal.exponent > INT_MAX)
- return INT_MAX;
- else if (normal.exponent < INT_MIN)
- return INT_MIN;
- else
- return normal.exponent;
+ if (LIBC_UNLIKELY(exponent > IntLogbConstants<T>::T_MAX ||
+ exponent < IntLogbConstants<T>::T_MIN)) {
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_INVALID);
+ return exponent > 0 ? IntLogbConstants<T>::T_MAX
+ : IntLogbConstants<T>::T_MIN;
+ }
+
+ return static_cast<T>(exponent);
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T logb(T x) {
+LIBC_INLINE constexpr T logb(T x) {
FPBits<T> bits(x);
- if (bits.is_zero()) {
- // TODO(Floating point exception): Raise div-by-zero exception.
- // TODO(errno): POSIX requires setting errno to ERANGE.
- return FPBits<T>::inf(Sign::NEG).get_val();
- } else if (bits.is_nan()) {
- return x;
- } else if (bits.is_inf()) {
- // Return positive infinity.
+ if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
+ if (bits.is_nan())
+ return x;
+
+ raise_except_if_required(FE_DIVBYZERO);
+
+ if (bits.is_zero()) {
+ set_errno_if_required(ERANGE);
+ return FPBits<T>::inf(Sign::NEG).get_val();
+ }
+ // bits is inf.
return FPBits<T>::inf().get_val();
}
- NormalFloat<T> normal(bits);
- return static_cast<T>(normal.exponent);
+ DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
+ return static_cast<T>(normal.get_unbiased_exponent());
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T ldexp(T x, int exp) {
- if (LIBC_UNLIKELY(exp == 0))
- return x;
+LIBC_INLINE constexpr T ldexp(T x, int exp) {
FPBits<T> bits(x);
- if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan()))
+ if (LIBC_UNLIKELY((exp == 0) || bits.is_zero() || bits.is_inf_or_nan()))
return x;
// NormalFloat uses int32_t to store the true exponent value. We should ensure
@@ -129,18 +154,40 @@ LIBC_INLINE T ldexp(T x, int exp) {
// early. Because the result of the ldexp operation can be a subnormal number,
// we need to accommodate the (mantissaWidth + 1) worth of shift in
// calculating the limit.
- int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
- if (exp > exp_limit)
- return FPBits<T>::inf(bits.sign()).get_val();
+ constexpr int EXP_LIMIT =
+ FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
+ if (LIBC_UNLIKELY(exp > EXP_LIMIT)) {
+ int rounding_mode = quick_get_round();
+ Sign sign = bits.sign();
+
+ if ((sign == Sign::POS && rounding_mode == FE_DOWNWARD) ||
+ (sign == Sign::NEG && rounding_mode == FE_UPWARD) ||
+ (rounding_mode == FE_TOWARDZERO))
+ return FPBits<T>::max_normal(sign).get_val();
+
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_OVERFLOW);
+ return FPBits<T>::inf(sign).get_val();
+ }
// Similarly on the negative side we return zero early if |exp| is too small.
- if (exp < -exp_limit)
- return FPBits<T>::zero(bits.sign()).get_val();
+ if (LIBC_UNLIKELY(exp < -EXP_LIMIT)) {
+ int rounding_mode = quick_get_round();
+ Sign sign = bits.sign();
+
+ if ((sign == Sign::POS && rounding_mode == FE_UPWARD) ||
+ (sign == Sign::NEG && rounding_mode == FE_DOWNWARD))
+ return FPBits<T>::min_subnormal(sign).get_val();
+
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_UNDERFLOW);
+ return FPBits<T>::zero(sign).get_val();
+ }
// For all other values, NormalFloat to T conversion handles it the right way.
- NormalFloat<T> normal(bits);
+ DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
normal.exponent += exp;
- return normal;
+ return static_cast<T>(normal);
}
template <typename T, typename U,
@@ -182,11 +229,36 @@ LIBC_INLINE T nextafter(T from, U to) {
return from_bits.get_val();
}
+template <bool IsDown, typename T,
+ cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE constexpr T nextupdown(T x) {
+ constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS;
+
+ FPBits<T> xbits(x);
+ if (xbits.is_nan() || xbits == FPBits<T>::max_normal(sign) ||
+ xbits == FPBits<T>::inf(sign))
+ return x;
+
+ using StorageType = typename FPBits<T>::StorageType;
+ if (x != T(0)) {
+ if (xbits.sign() == sign) {
+ xbits = FPBits<T>(StorageType(xbits.uintval() + 1));
+ } else {
+ xbits = FPBits<T>(StorageType(xbits.uintval() - 1));
+ }
+ } else {
+ xbits = FPBits<T>::min_subnormal(sign);
+ }
+
+ return xbits.get_val();
+}
+
} // namespace fputil
} // namespace LIBC_NAMESPACE
-#ifdef LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#include "x86_64/NextAfterLongDouble.h"
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#include "x86_64/NextUpDownLongDouble.h"
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_MANIPULATIONFUNCTIONS_H
diff --git a/src/__support/FPUtil/NearestIntegerOperations.h b/src/__support/FPUtil/NearestIntegerOperations.h
index 19ae75ea7889..6b28e7ffb387 100644
--- a/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/src/__support/FPUtil/NearestIntegerOperations.h
@@ -13,11 +13,10 @@
#include "FPBits.h"
#include "rounding_mode.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
-#include <math.h>
-
namespace LIBC_NAMESPACE {
namespace fputil {
@@ -141,8 +140,9 @@ LIBC_INLINE T round(T x) {
}
}
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T round_using_current_rounding_mode(T x) {
+template <typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
+round_using_specific_rounding_mode(T x, int rnd) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
@@ -152,7 +152,6 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
- int rounding_mode = quick_get_round();
// If the exponent is greater than the most negative mantissa
// exponent, then x is already an integer.
@@ -160,20 +159,23 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
return x;
if (exponent <= -1) {
- switch (rounding_mode) {
- case FE_DOWNWARD:
+ switch (rnd) {
+ case FP_INT_DOWNWARD:
return is_neg ? T(-1.0) : T(0.0);
- case FE_UPWARD:
+ case FP_INT_UPWARD:
return is_neg ? T(-0.0) : T(1.0);
- case FE_TOWARDZERO:
+ case FP_INT_TOWARDZERO:
return is_neg ? T(-0.0) : T(0.0);
- case FE_TONEAREST:
+ case FP_INT_TONEARESTFROMZERO:
+ if (exponent < -1)
+ return is_neg ? T(-0.0) : T(0.0); // abs(x) < 0.5
+ return is_neg ? T(-1.0) : T(1.0); // abs(x) >= 0.5
+ case FP_INT_TONEAREST:
+ default:
if (exponent <= -2 || bits.get_mantissa() == 0)
return is_neg ? T(-0.0) : T(0.0); // abs(x) <= 0.5
else
return is_neg ? T(-1.0) : T(1.0); // abs(x) > 0.5
- default:
- __builtin_unreachable();
}
}
@@ -195,14 +197,19 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
StorageType trunc_is_odd =
new_bits.get_mantissa() & (StorageType(1) << trim_size);
- switch (rounding_mode) {
- case FE_DOWNWARD:
+ switch (rnd) {
+ case FP_INT_DOWNWARD:
return is_neg ? trunc_value - T(1.0) : trunc_value;
- case FE_UPWARD:
+ case FP_INT_UPWARD:
return is_neg ? trunc_value : trunc_value + T(1.0);
- case FE_TOWARDZERO:
+ case FP_INT_TOWARDZERO:
return trunc_value;
- case FE_TONEAREST:
+ case FP_INT_TONEARESTFROMZERO:
+ if (trim_value >= half_value)
+ return is_neg ? trunc_value - T(1.0) : trunc_value + T(1.0);
+ return trunc_value;
+ case FP_INT_TONEAREST:
+ default:
if (trim_value > half_value) {
return is_neg ? trunc_value - T(1.0) : trunc_value + T(1.0);
} else if (trim_value == half_value) {
@@ -215,11 +222,109 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
} else {
return trunc_value;
}
+ }
+}
+
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
+round_using_current_rounding_mode(T x) {
+ int rounding_mode = quick_get_round();
+
+ switch (rounding_mode) {
+ case FE_DOWNWARD:
+ return round_using_specific_rounding_mode(x, FP_INT_DOWNWARD);
+ case FE_UPWARD:
+ return round_using_specific_rounding_mode(x, FP_INT_UPWARD);
+ case FE_TOWARDZERO:
+ return round_using_specific_rounding_mode(x, FP_INT_TOWARDZERO);
+ case FE_TONEAREST:
+ return round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
default:
__builtin_unreachable();
}
}
+template <bool IsSigned, typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
+fromfp(T x, int rnd, unsigned int width) {
+ using StorageType = typename FPBits<T>::StorageType;
+
+ constexpr StorageType EXPLICIT_BIT =
+ FPBits<T>::SIG_MASK - FPBits<T>::FRACTION_MASK;
+
+ if (width == 0U) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+
+ FPBits<T> bits(x);
+
+ if (bits.is_inf_or_nan()) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+
+ T rounded_value = round_using_specific_rounding_mode(x, rnd);
+
+ if constexpr (IsSigned) {
+ // T can't hold a finite number >= 2.0 * 2^EXP_BIAS.
+ if (width - 1 > FPBits<T>::EXP_BIAS)
+ return rounded_value;
+
+ StorageType range_exp = width - 1U + FPBits<T>::EXP_BIAS;
+ // rounded_value < -2^(width - 1)
+ T range_min =
+ FPBits<T>::create_value(Sign::NEG, range_exp, EXPLICIT_BIT).get_val();
+ if (rounded_value < range_min) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+ // rounded_value > 2^(width - 1) - 1
+ T range_max =
+ FPBits<T>::create_value(Sign::POS, range_exp, EXPLICIT_BIT).get_val() -
+ T(1.0);
+ if (rounded_value > range_max) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+
+ return rounded_value;
+ }
+
+ if (rounded_value < T(0.0)) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+
+ // T can't hold a finite number >= 2.0 * 2^EXP_BIAS.
+ if (width > FPBits<T>::EXP_BIAS)
+ return rounded_value;
+
+ StorageType range_exp = width + FPBits<T>::EXP_BIAS;
+ // rounded_value > 2^width - 1
+ T range_max =
+ FPBits<T>::create_value(Sign::POS, range_exp, EXPLICIT_BIT).get_val() -
+ T(1.0);
+ if (rounded_value > range_max) {
+ raise_except_if_required(FE_INVALID);
+ return FPBits<T>::quiet_nan().get_val();
+ }
+
+ return rounded_value;
+}
+
+template <bool IsSigned, typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
+fromfpx(T x, int rnd, unsigned int width) {
+ T rounded_value = fromfp<IsSigned>(x, rnd, width);
+ FPBits<T> bits(rounded_value);
+
+ if (!bits.is_nan() && rounded_value != x)
+ raise_except_if_required(FE_INEXACT);
+
+ return rounded_value;
+}
+
namespace internal {
template <typename F, typename I,
diff --git a/src/__support/FPUtil/NormalFloat.h b/src/__support/FPUtil/NormalFloat.h
index 57a401d911fc..8bc1fecd653b 100644
--- a/src/__support/FPUtil/NormalFloat.h
+++ b/src/__support/FPUtil/NormalFloat.h
@@ -172,7 +172,7 @@ private:
}
};
-#ifdef LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
template <>
LIBC_INLINE void
NormalFloat<long double>::init_from_bits(FPBits<long double> bits) {
@@ -261,7 +261,7 @@ template <> LIBC_INLINE NormalFloat<long double>::operator long double() const {
result.set_implicit_bit(1);
return result.get_val();
}
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
} // namespace fputil
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/FPUtil/XFloat.h b/src/__support/FPUtil/XFloat.h
deleted file mode 100644
index fe334f8a3301..000000000000
--- a/src/__support/FPUtil/XFloat.h
+++ /dev/null
@@ -1,180 +0,0 @@
-//===-- Utility class to manipulate wide floats. ----------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "FPBits.h"
-#include "NormalFloat.h"
-#include "src/__support/UInt.h"
-
-#include <stdint.h>
-
-namespace LIBC_NAMESPACE {
-namespace fputil {
-
-// Store and manipulate positive double precision numbers at |Precision| bits.
-template <size_t Precision> class XFloat {
- static constexpr uint64_t OneMask = (uint64_t(1) << 63);
- UInt<Precision> man;
- static constexpr uint64_t WORDCOUNT = Precision / 64;
- int exp;
-
- size_t bit_width(uint64_t x) {
- if (x == 0)
- return 0;
- size_t shift = 0;
- while ((OneMask & x) == 0) {
- ++shift;
- x <<= 1;
- }
- return 64 - shift;
- }
-
-public:
- XFloat() : exp(0) {
- for (int i = 0; i < WORDCOUNT; ++i)
- man[i] = 0;
- }
-
- XFloat(const XFloat &other) : exp(other.exp) {
- for (int i = 0; i < WORDCOUNT; ++i)
- man[i] = other.man[i];
- }
-
- explicit XFloat(double x) {
- auto xn = NormalFloat<double>(x);
- exp = xn.exponent;
- man[WORDCOUNT - 1] = xn.mantissa << 11;
- for (int i = 0; i < WORDCOUNT - 1; ++i)
- man[i] = 0;
- }
-
- XFloat(int e, const UInt<Precision> &bits) : exp(e) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- man[i] = bits[i];
- }
-
- // Multiply this number with x and store the result in this number.
- void mul(double x) {
- auto xn = NormalFloat<double>(x);
- exp += xn.exponent;
- uint64_t carry = man.mul(xn.mantissa << 11);
- size_t carry_width = bit_width(carry);
- carry_width = (carry_width == 64 ? 64 : 63);
- man.shift_right(carry_width);
- man[WORDCOUNT - 1] = man[WORDCOUNT - 1] + (carry << (64 - carry_width));
- exp += carry_width == 64 ? 1 : 0;
- normalize();
- }
-
- void drop_int() {
- if (exp < 0)
- return;
- if (exp > int(Precision - 1)) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- man[i] = 0;
- return;
- }
-
- man.shift_left(exp + 1);
- man.shift_right(exp + 1);
-
- normalize();
- }
-
- double mul(const XFloat<Precision> &other) {
- constexpr size_t row_words = 2 * WORDCOUNT + 1;
- constexpr size_t row_precision = row_words * 64;
- constexpr size_t result_bits = 2 * Precision;
- UInt<row_precision> rows[WORDCOUNT];
-
- for (size_t r = 0; r < WORDCOUNT; ++r) {
- for (size_t i = 0; i < row_words; ++i) {
- if (i < WORDCOUNT)
- rows[r][i] = man[i];
- else
- rows[r][i] = 0;
- }
- rows[r].mul(other.man[r]);
- rows[r].shift_left(r * 64);
- }
-
- for (size_t r = 1; r < WORDCOUNT; ++r) {
- rows[0].add(rows[r]);
- }
- int result_exp = exp + other.exp;
- uint64_t carry = rows[0][row_words - 1];
- if (carry) {
- size_t carry_width = bit_width(carry);
- rows[0].shift_right(carry_width);
- rows[0][row_words - 2] =
- rows[0][row_words - 2] + (carry << (64 - carry_width));
- result_exp += carry_width;
- }
-
- if (rows[0][row_words - 2] & OneMask) {
- ++result_exp;
- } else {
- rows[0].shift_left(1);
- }
-
- UInt<result_bits> result_man;
- for (size_t i = 0; i < result_bits / 64; ++i)
- result_man[i] = rows[0][i];
- XFloat<result_bits> result(result_exp, result_man);
- result.normalize();
- return double(result);
- }
-
- explicit operator double() {
- normalize();
-
- constexpr uint64_t one = uint64_t(1) << 10;
- constexpr uint64_t excess_mask = (one << 1) - 1;
- uint64_t excess = man[WORDCOUNT - 1] & excess_mask;
- uint64_t new_man = man[WORDCOUNT - 1] >> 11;
- if (excess > one) {
- // We have to round up.
- ++new_man;
- } else if (excess == one) {
- bool greater_than_one = false;
- for (size_t i = 0; i < WORDCOUNT - 1; ++i) {
- greater_than_one = (man[i] != 0);
- if (greater_than_one)
- break;
- }
- if (greater_than_one || (new_man & 1) != 0) {
- ++new_man;
- }
- }
-
- if (new_man == (uint64_t(1) << 53))
- ++exp;
-
- // We use NormalFloat as it can produce subnormal numbers or underflow to 0
- // if necessary.
- NormalFloat<double> d(exp, new_man, 0);
- return double(d);
- }
-
- // Normalizes this number.
- void normalize() {
- uint64_t man_bits = 0;
- for (size_t i = 0; i < WORDCOUNT; ++i)
- man_bits |= man[i];
-
- if (man_bits == 0)
- return;
-
- while ((man[WORDCOUNT - 1] & OneMask) == 0) {
- man.shift_left(1);
- --exp;
- }
- }
-};
-
-} // namespace fputil
-} // namespace LIBC_NAMESPACE
diff --git a/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index ea1fd68a5fcd..fd915373020e 100644
--- a/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -161,8 +161,8 @@ LIBC_INLINE int set_except(int excepts) {
LIBC_INLINE int raise_except(int excepts) {
float zero = 0.0f;
float one = 1.0f;
- float large_value = FPBits<float>::max_normal();
- float small_value = FPBits<float>::min_normal();
+ float large_value = FPBits<float>::max_normal().get_val();
+ float small_value = FPBits<float>::min_normal().get_val();
auto divfunc = [](float a, float b) {
__asm__ __volatile__("ldr s0, %0\n\t"
"ldr s1, %1\n\t"
@@ -277,8 +277,8 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
return 0;
}
const FEnv::FPState *state = reinterpret_cast<const FEnv::FPState *>(envp);
- FEnv::set_control_word(state->ControlWord);
- FEnv::set_status_word(state->StatusWord);
+ FEnv::set_control_word(static_cast<uint32_t>(state->ControlWord));
+ FEnv::set_status_word(static_cast<uint32_t>(state->StatusWord));
return 0;
}
diff --git a/src/__support/FPUtil/dyadic_float.h b/src/__support/FPUtil/dyadic_float.h
index 888d7ffec241..e0c205f52383 100644
--- a/src/__support/FPUtil/dyadic_float.h
+++ b/src/__support/FPUtil/dyadic_float.h
@@ -19,7 +19,7 @@
namespace LIBC_NAMESPACE::fputil {
-// A generic class to perform comuptations of high precision floating points.
+// A generic class to perform computations of high precision floating points.
// We store the value in dyadic format, including 3 fields:
// sign : boolean value - false means positive, true means negative
// exponent: the exponent value of the least significant bit of the mantissa.
@@ -31,73 +31,85 @@ namespace LIBC_NAMESPACE::fputil {
// To simplify and improve the efficiency, many functions will assume that the
// inputs are normal.
template <size_t Bits> struct DyadicFloat {
- using MantissaType = LIBC_NAMESPACE::cpp::UInt<Bits>;
+ using MantissaType = LIBC_NAMESPACE::UInt<Bits>;
Sign sign = Sign::POS;
int exponent = 0;
MantissaType mantissa = MantissaType(0);
- constexpr DyadicFloat() = default;
+ LIBC_INLINE constexpr DyadicFloat() = default;
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
- DyadicFloat(T x) {
+ LIBC_INLINE constexpr DyadicFloat(T x) {
static_assert(FPBits<T>::FRACTION_LEN < Bits);
FPBits<T> x_bits(x);
sign = x_bits.sign();
- exponent = x_bits.get_exponent() - FPBits<T>::FRACTION_LEN;
+ exponent = x_bits.get_explicit_exponent() - FPBits<T>::FRACTION_LEN;
mantissa = MantissaType(x_bits.get_explicit_mantissa());
normalize();
}
- constexpr DyadicFloat(Sign s, int e, MantissaType m)
+ LIBC_INLINE constexpr DyadicFloat(Sign s, int e, MantissaType m)
: sign(s), exponent(e), mantissa(m) {
normalize();
}
// Normalizing the mantissa, bringing the leading 1 bit to the most
// significant bit.
- constexpr DyadicFloat &normalize() {
+ LIBC_INLINE constexpr DyadicFloat &normalize() {
if (!mantissa.is_zero()) {
- int shift_length = static_cast<int>(mantissa.clz());
+ int shift_length = cpp::countl_zero(mantissa);
exponent -= shift_length;
- mantissa.shift_left(static_cast<size_t>(shift_length));
+ mantissa <<= static_cast<size_t>(shift_length);
}
return *this;
}
// Used for aligning exponents. Output might not be normalized.
- DyadicFloat &shift_left(int shift_length) {
+ LIBC_INLINE constexpr DyadicFloat &shift_left(int shift_length) {
exponent -= shift_length;
mantissa <<= static_cast<size_t>(shift_length);
return *this;
}
// Used for aligning exponents. Output might not be normalized.
- DyadicFloat &shift_right(int shift_length) {
+ LIBC_INLINE constexpr DyadicFloat &shift_right(int shift_length) {
exponent += shift_length;
mantissa >>= static_cast<size_t>(shift_length);
return *this;
}
- // Assume that it is already normalized and output is not underflow.
+ // Assume that it is already normalized. Output the unbiased exponent.
+ LIBC_INLINE constexpr int get_unbiased_exponent() const {
+ return exponent + (Bits - 1);
+ }
+
+ // Assume that it is already normalized.
// Output is rounded correctly with respect to the current rounding mode.
- // TODO(lntue): Add support for underflow.
- // TODO(lntue): Test or add specialization for x86 long double.
template <typename T,
typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
(FPBits<T>::FRACTION_LEN < Bits),
void>>
- explicit operator T() const {
- // TODO(lntue): Do we need to treat signed zeros properly?
- if (mantissa.is_zero())
- return 0.0;
+ LIBC_INLINE explicit constexpr operator T() const {
+ if (LIBC_UNLIKELY(mantissa.is_zero()))
+ return FPBits<T>::zero(sign).get_val();
// Assume that it is normalized, and output is also normal.
constexpr uint32_t PRECISION = FPBits<T>::FRACTION_LEN + 1;
using output_bits_t = typename FPBits<T>::StorageType;
+ constexpr output_bits_t IMPLICIT_MASK =
+ FPBits<T>::SIG_MASK - FPBits<T>::FRACTION_MASK;
int exp_hi = exponent + static_cast<int>((Bits - 1) + FPBits<T>::EXP_BIAS);
+ if (LIBC_UNLIKELY(exp_hi > 2 * FPBits<T>::EXP_BIAS)) {
+ // Results overflow.
+ T d_hi =
+ FPBits<T>::create_value(sign, 2 * FPBits<T>::EXP_BIAS, IMPLICIT_MASK)
+ .get_val();
+ return T(2) * d_hi;
+ }
+
bool denorm = false;
uint32_t shift = Bits - PRECISION;
if (LIBC_UNLIKELY(exp_hi <= 0)) {
@@ -112,56 +124,64 @@ template <size_t Bits> struct DyadicFloat {
MantissaType m_hi(mantissa >> shift);
- T d_hi = FPBits<T>::create_value(sign, exp_hi,
- static_cast<output_bits_t>(m_hi) &
- FPBits<T>::FRACTION_MASK)
+ T d_hi = FPBits<T>::create_value(
+ sign, exp_hi,
+ (static_cast<output_bits_t>(m_hi) & FPBits<T>::SIG_MASK) |
+ IMPLICIT_MASK)
.get_val();
- const MantissaType round_mask = MantissaType(1) << (shift - 1);
- const MantissaType sticky_mask = round_mask - MantissaType(1);
+ MantissaType round_mask = MantissaType(1) << (shift - 1);
+ MantissaType sticky_mask = round_mask - MantissaType(1);
bool round_bit = !(mantissa & round_mask).is_zero();
bool sticky_bit = !(mantissa & sticky_mask).is_zero();
int round_and_sticky = int(round_bit) * 2 + int(sticky_bit);
T d_lo;
+
if (LIBC_UNLIKELY(exp_lo <= 0)) {
// d_lo is denormal, but the output is normal.
int scale_up_exponent = 2 * PRECISION;
T scale_up_factor =
FPBits<T>::create_value(sign, FPBits<T>::EXP_BIAS + scale_up_exponent,
- output_bits_t(0))
+ IMPLICIT_MASK)
.get_val();
T scale_down_factor =
FPBits<T>::create_value(sign, FPBits<T>::EXP_BIAS - scale_up_exponent,
- output_bits_t(0))
+ IMPLICIT_MASK)
.get_val();
d_lo = FPBits<T>::create_value(sign, exp_lo + scale_up_exponent,
- output_bits_t(0))
+ IMPLICIT_MASK)
.get_val();
return multiply_add(d_lo, T(round_and_sticky), d_hi * scale_up_factor) *
scale_down_factor;
}
- d_lo = FPBits<T>::create_value(sign, exp_lo, output_bits_t(0)).get_val();
+ d_lo = FPBits<T>::create_value(sign, exp_lo, IMPLICIT_MASK).get_val();
// Still correct without FMA instructions if `d_lo` is not underflow.
T r = multiply_add(d_lo, T(round_and_sticky), d_hi);
if (LIBC_UNLIKELY(denorm)) {
- // Output is denormal, simply clear the exponent field.
- output_bits_t clear_exp = output_bits_t(exp_hi)
- << FPBits<T>::FRACTION_LEN;
+ // Exponent before rounding is in denormal range, simply clear the
+ // exponent field.
+ output_bits_t clear_exp = (output_bits_t(exp_hi) << FPBits<T>::SIG_LEN);
output_bits_t r_bits = FPBits<T>(r).uintval() - clear_exp;
+ if (!(r_bits & FPBits<T>::EXP_MASK)) {
+ // Output is denormal after rounding, clear the implicit bit for 80-bit
+ // long double.
+ r_bits -= IMPLICIT_MASK;
+ }
+
return FPBits<T>(r_bits).get_val();
}
return r;
}
- explicit operator MantissaType() const {
+ LIBC_INLINE explicit constexpr operator MantissaType() const {
if (mantissa.is_zero())
return 0;
@@ -193,8 +213,8 @@ template <size_t Bits> struct DyadicFloat {
// don't need to normalize the inputs again in this function. If the inputs are
// not normalized, the results might lose precision significantly.
template <size_t Bits>
-constexpr DyadicFloat<Bits> quick_add(DyadicFloat<Bits> a,
- DyadicFloat<Bits> b) {
+LIBC_INLINE constexpr DyadicFloat<Bits> quick_add(DyadicFloat<Bits> a,
+ DyadicFloat<Bits> b) {
if (LIBC_UNLIKELY(a.mantissa.is_zero()))
return b;
if (LIBC_UNLIKELY(b.mantissa.is_zero()))
@@ -213,10 +233,10 @@ constexpr DyadicFloat<Bits> quick_add(DyadicFloat<Bits> a,
result.sign = a.sign;
result.exponent = a.exponent;
result.mantissa = a.mantissa;
- if (result.mantissa.add(b.mantissa)) {
+ if (result.mantissa.add_overflow(b.mantissa)) {
// Mantissa addition overflow.
result.shift_right(1);
- result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORDCOUNT - 1] |=
+ result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] |=
(uint64_t(1) << 63);
}
// Result is already normalized.
@@ -243,13 +263,13 @@ constexpr DyadicFloat<Bits> quick_add(DyadicFloat<Bits> a,
// result.mantissa = quick_mul_hi(a.mantissa + b.mantissa)
// ~ (full product a.mantissa * b.mantissa) >> Bits.
// The errors compared to the mathematical product is bounded by:
-// 2 * errors of quick_mul_hi = 2 * (UInt<Bits>::WORDCOUNT - 1) in ULPs.
+// 2 * errors of quick_mul_hi = 2 * (UInt<Bits>::WORD_COUNT - 1) in ULPs.
// Assume inputs are normalized (by constructors or other functions) so that we
// don't need to normalize the inputs again in this function. If the inputs are
// not normalized, the results might lose precision significantly.
template <size_t Bits>
-constexpr DyadicFloat<Bits> quick_mul(DyadicFloat<Bits> a,
- DyadicFloat<Bits> b) {
+LIBC_INLINE constexpr DyadicFloat<Bits> quick_mul(DyadicFloat<Bits> a,
+ DyadicFloat<Bits> b) {
DyadicFloat<Bits> result;
result.sign = (a.sign != b.sign) ? Sign::NEG : Sign::POS;
result.exponent = a.exponent + b.exponent + int(Bits);
@@ -258,7 +278,7 @@ constexpr DyadicFloat<Bits> quick_mul(DyadicFloat<Bits> a,
result.mantissa = a.mantissa.quick_mul_hi(b.mantissa);
// Check the leading bit directly, should be faster than using clz in
// normalize().
- if (result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORDCOUNT - 1] >>
+ if (result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] >>
63 ==
0)
result.shift_left(1);
@@ -270,16 +290,17 @@ constexpr DyadicFloat<Bits> quick_mul(DyadicFloat<Bits> a,
// Simple polynomial approximation.
template <size_t Bits>
-constexpr DyadicFloat<Bits> multiply_add(const DyadicFloat<Bits> &a,
- const DyadicFloat<Bits> &b,
- const DyadicFloat<Bits> &c) {
+LIBC_INLINE constexpr DyadicFloat<Bits>
+multiply_add(const DyadicFloat<Bits> &a, const DyadicFloat<Bits> &b,
+ const DyadicFloat<Bits> &c) {
return quick_add(c, quick_mul(a, b));
}
// Simple exponentiation implementation for printf. Only handles positive
// exponents, since division isn't implemented.
template <size_t Bits>
-constexpr DyadicFloat<Bits> pow_n(DyadicFloat<Bits> a, uint32_t power) {
+LIBC_INLINE constexpr DyadicFloat<Bits> pow_n(DyadicFloat<Bits> a,
+ uint32_t power) {
DyadicFloat<Bits> result = 1.0;
DyadicFloat<Bits> cur_power = a;
@@ -294,7 +315,8 @@ constexpr DyadicFloat<Bits> pow_n(DyadicFloat<Bits> a, uint32_t power) {
}
template <size_t Bits>
-constexpr DyadicFloat<Bits> mul_pow_2(DyadicFloat<Bits> a, int32_t pow_2) {
+LIBC_INLINE constexpr DyadicFloat<Bits> mul_pow_2(DyadicFloat<Bits> a,
+ int32_t pow_2) {
DyadicFloat<Bits> result = a;
result.exponent += pow_2;
return result;
diff --git a/src/__support/FPUtil/fpbits_str.h b/src/__support/FPUtil/fpbits_str.h
index a1654cddad74..97689867da4d 100644
--- a/src/__support/FPUtil/fpbits_str.h
+++ b/src/__support/FPUtil/fpbits_str.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FP_BITS_STR_H
-#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FP_BITS_STR_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/type_traits.h"
@@ -35,7 +35,6 @@ using ZeroPaddedHexFmt = IntegerToString<
// floating encoding.
template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
using StorageType = typename fputil::FPBits<T>::StorageType;
- using Sign = fputil::Sign;
if (x.is_nan())
return "(NaN)";
@@ -73,4 +72,4 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FP_BITS_STR_H
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
diff --git a/src/__support/FPUtil/generic/FMod.h b/src/__support/FPUtil/generic/FMod.h
index 2d31290bc4bc..24fb264b779b 100644
--- a/src/__support/FPUtil/generic/FMod.h
+++ b/src/__support/FPUtil/generic/FMod.h
@@ -117,63 +117,9 @@ namespace generic {
// be implemented in another handler.
// Signaling NaN converted to quiet NaN with FE_INVALID exception.
// https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1011.htm
-template <typename T> struct FModExceptionalInputHandler {
-
- static_assert(cpp::is_floating_point_v<T>,
- "FModCStandardWrapper instantiated with invalid type.");
-
- LIBC_INLINE static bool pre_check(T x, T y, T &out) {
- using FPB = fputil::FPBits<T>;
- const T quiet_nan = FPB::quiet_nan().get_val();
- FPB sx(x), sy(y);
- if (LIBC_LIKELY(!sy.is_zero() && !sy.is_inf_or_nan() &&
- !sx.is_inf_or_nan())) {
- return false;
- }
-
- if (sx.is_nan() || sy.is_nan()) {
- if ((sx.is_nan() && !sx.is_quiet_nan()) ||
- (sy.is_nan() && !sy.is_quiet_nan()))
- fputil::raise_except_if_required(FE_INVALID);
- out = quiet_nan;
- return true;
- }
-
- if (sx.is_inf() || sy.is_zero()) {
- fputil::raise_except_if_required(FE_INVALID);
- fputil::set_errno_if_required(EDOM);
- out = quiet_nan;
- return true;
- }
-
- if (sy.is_inf()) {
- out = x;
- return true;
- }
-
- // case where x == 0
- out = x;
- return true;
- }
-};
-
-template <typename T> struct FModFastMathWrapper {
-
- static_assert(cpp::is_floating_point_v<T>,
- "FModFastMathWrapper instantiated with invalid type.");
-
- static bool pre_check(T, T, T &) { return false; }
-};
-
-template <typename T> class FModDivisionSimpleHelper {
-private:
- using StorageType = typename FPBits<T>::StorageType;
-
-public:
- LIBC_INLINE constexpr static StorageType execute(int exp_diff,
- int sides_zeroes_count,
- StorageType m_x,
- StorageType m_y) {
+template <typename T> struct FModDivisionSimpleHelper {
+ LIBC_INLINE constexpr static T execute(int exp_diff, int sides_zeroes_count,
+ T m_x, T m_y) {
while (exp_diff > sides_zeroes_count) {
exp_diff -= sides_zeroes_count;
m_x <<= sides_zeroes_count;
@@ -185,28 +131,21 @@ public:
}
};
-template <typename T> class FModDivisionInvMultHelper {
-private:
- using FPB = FPBits<T>;
- using StorageType = typename FPB::StorageType;
-
-public:
- LIBC_INLINE constexpr static StorageType execute(int exp_diff,
- int sides_zeroes_count,
- StorageType m_x,
- StorageType m_y) {
+template <typename T> struct FModDivisionInvMultHelper {
+ LIBC_INLINE constexpr static T execute(int exp_diff, int sides_zeroes_count,
+ T m_x, T m_y) {
+ constexpr int LENGTH = sizeof(T) * CHAR_BIT;
if (exp_diff > sides_zeroes_count) {
- StorageType inv_hy = (cpp::numeric_limits<StorageType>::max() / m_y);
+ T inv_hy = (cpp::numeric_limits<T>::max() / m_y);
while (exp_diff > sides_zeroes_count) {
exp_diff -= sides_zeroes_count;
- StorageType hd =
- (m_x * inv_hy) >> (FPB::TOTAL_LEN - sides_zeroes_count);
+ T hd = (m_x * inv_hy) >> (LENGTH - sides_zeroes_count);
m_x <<= sides_zeroes_count;
m_x -= hd * m_y;
while (LIBC_UNLIKELY(m_x > m_y))
m_x -= m_y;
}
- StorageType hd = (m_x * inv_hy) >> (FPB::TOTAL_LEN - exp_diff);
+ T hd = (m_x * inv_hy) >> (LENGTH - exp_diff);
m_x <<= exp_diff;
m_x -= hd * m_y;
while (LIBC_UNLIKELY(m_x > m_y))
@@ -219,22 +158,49 @@ public:
}
};
-template <typename T, class Wrapper = FModExceptionalInputHandler<T>,
- class DivisionHelper = FModDivisionSimpleHelper<T>>
+template <typename T, typename U = typename FPBits<T>::StorageType,
+ typename DivisionHelper = FModDivisionSimpleHelper<U>>
class FMod {
- static_assert(cpp::is_floating_point_v<T>,
+ static_assert(cpp::is_floating_point_v<T> && cpp::is_unsigned_v<U> &&
+ (sizeof(U) * CHAR_BIT > FPBits<T>::FRACTION_LEN),
"FMod instantiated with invalid type.");
private:
using FPB = FPBits<T>;
using StorageType = typename FPB::StorageType;
+ LIBC_INLINE static bool pre_check(T x, T y, T &out) {
+ using FPB = fputil::FPBits<T>;
+ const T quiet_nan = FPB::quiet_nan().get_val();
+ FPB sx(x), sy(y);
+ if (LIBC_LIKELY(!sy.is_zero() && !sy.is_inf_or_nan() &&
+ !sx.is_inf_or_nan()))
+ return false;
+
+ if (sx.is_nan() || sy.is_nan()) {
+ if (sx.is_signaling_nan() || sy.is_signaling_nan())
+ fputil::raise_except_if_required(FE_INVALID);
+ out = quiet_nan;
+ return true;
+ }
+
+ if (sx.is_inf() || sy.is_zero()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ fputil::set_errno_if_required(EDOM);
+ out = quiet_nan;
+ return true;
+ }
+
+ out = x;
+ return true;
+ }
+
LIBC_INLINE static constexpr FPB eval_internal(FPB sx, FPB sy) {
if (LIBC_LIKELY(sx.uintval() <= sy.uintval())) {
if (sx.uintval() < sy.uintval())
return sx; // |x|<|y| return x
- return FPB(FPB::zero()); // |x|=|y| return 0.0
+ return FPB::zero(); // |x|=|y| return 0.0
}
int e_x = sx.get_biased_exponent();
@@ -247,11 +213,11 @@ private:
StorageType m_y = sy.get_explicit_mantissa();
StorageType d = (e_x == e_y) ? (m_x - m_y) : (m_x << (e_x - e_y)) % m_y;
if (d == 0)
- return FPB(FPB::zero());
+ return FPB::zero();
// iy - 1 because of "zero power" for number with power 1
return FPB::make_value(d, e_y - 1);
}
- /* Both subnormal special case. */
+ // Both subnormal special case.
if (LIBC_UNLIKELY(e_x == 0 && e_y == 0)) {
FPB d;
d.set_mantissa(sx.uintval() % sy.uintval());
@@ -259,15 +225,17 @@ private:
}
// Note that hx is not subnormal by conditions above.
- StorageType m_x = sx.get_explicit_mantissa();
+ U m_x = static_cast<U>(sx.get_explicit_mantissa());
e_x--;
- StorageType m_y = sy.get_explicit_mantissa();
- int lead_zeros_m_y = FPB::EXP_LEN;
+ U m_y = static_cast<U>(sy.get_explicit_mantissa());
+ constexpr int DEFAULT_LEAD_ZEROS =
+ sizeof(U) * CHAR_BIT - FPB::FRACTION_LEN - 1;
+ int lead_zeros_m_y = DEFAULT_LEAD_ZEROS;
if (LIBC_LIKELY(e_y > 0)) {
e_y--;
} else {
- m_y = sy.get_mantissa();
+ m_y = static_cast<U>(sy.get_mantissa());
lead_zeros_m_y = cpp::countl_zero(m_y);
}
@@ -286,26 +254,27 @@ private:
{
// Shift hx left until the end or n = 0
- int left_shift = exp_diff < int(FPB::EXP_LEN) ? exp_diff : FPB::EXP_LEN;
+ int left_shift =
+ exp_diff < DEFAULT_LEAD_ZEROS ? exp_diff : DEFAULT_LEAD_ZEROS;
m_x <<= left_shift;
exp_diff -= left_shift;
}
m_x %= m_y;
if (LIBC_UNLIKELY(m_x == 0))
- return FPB(FPB::zero());
+ return FPB::zero();
if (exp_diff == 0)
- return FPB::make_value(m_x, e_y);
+ return FPB::make_value(static_cast<StorageType>(m_x), e_y);
- /* hx next can't be 0, because hx < hy, hy % 2 == 1 hx * 2^i % hy != 0 */
+ // hx next can't be 0, because hx < hy, hy % 2 == 1 hx * 2^i % hy != 0
m_x = DivisionHelper::execute(exp_diff, sides_zeroes_count, m_x, m_y);
- return FPB::make_value(m_x, e_y);
+ return FPB::make_value(static_cast<StorageType>(m_x), e_y);
}
public:
LIBC_INLINE static T eval(T x, T y) {
- if (T out; Wrapper::pre_check(x, y, out))
+ if (T out; LIBC_UNLIKELY(pre_check(x, y, out)))
return out;
FPB sx(x), sy(y);
Sign sign = sx.sign();
diff --git a/src/__support/FPUtil/generic/sqrt.h b/src/__support/FPUtil/generic/sqrt.h
index 702de3f04a9b..b6b4aaecb2cc 100644
--- a/src/__support/FPUtil/generic/sqrt.h
+++ b/src/__support/FPUtil/generic/sqrt.h
@@ -27,27 +27,28 @@ template <typename T> struct SpecialLongDouble {
static constexpr bool VALUE = false;
};
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <> struct SpecialLongDouble<long double> {
static constexpr bool VALUE = true;
};
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
template <typename T>
LIBC_INLINE void normalize(int &exponent,
typename FPBits<T>::StorageType &mantissa) {
- const int shift = cpp::countl_zero(mantissa) -
- (8 * sizeof(mantissa) - 1 - FPBits<T>::FRACTION_LEN);
+ const int shift =
+ cpp::countl_zero(mantissa) -
+ (8 * static_cast<int>(sizeof(mantissa)) - 1 - FPBits<T>::FRACTION_LEN);
exponent -= shift;
mantissa <<= shift;
}
-#ifdef LIBC_LONG_DOUBLE_IS_FLOAT64
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
template <>
LIBC_INLINE void normalize<long double>(int &exponent, uint64_t &mantissa) {
normalize<double>(exponent, mantissa);
}
-#elif !defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#elif !defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <>
LIBC_INLINE void normalize<long double>(int &exponent, UInt128 &mantissa) {
const uint64_t hi_bits = static_cast<uint64_t>(mantissa >> 64);
@@ -78,21 +79,16 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
FPBits_t bits(x);
- if (bits.is_inf_or_nan()) {
- if (bits.is_neg() && (bits.get_mantissa() == 0)) {
- // sqrt(-Inf) = NaN
- return FLT_NAN;
- } else {
- // sqrt(NaN) = NaN
- // sqrt(+Inf) = +Inf
- return x;
- }
- } else if (bits.is_zero()) {
+ if (bits == FPBits_t::inf(Sign::POS) || bits.is_zero() || bits.is_nan()) {
+ // sqrt(+Inf) = +Inf
// sqrt(+0) = +0
// sqrt(-0) = -0
+ // sqrt(NaN) = NaN
+ // sqrt(-NaN) = -NaN
return x;
} else if (bits.is_neg()) {
- // sqrt( negative numbers ) = NaN
+ // sqrt(-Inf) = NaN
+ // sqrt(-x) = NaN
return FLT_NAN;
} else {
int x_exp = bits.get_exponent();
diff --git a/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
index 74a536c04817..656ade4f7735 100644
--- a/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
+++ b/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
@@ -34,7 +34,7 @@ LIBC_INLINE long double sqrt(long double x);
// Correctly rounded SQRT for all rounding modes.
// Shift-and-add algorithm.
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
LIBC_INLINE long double sqrt(long double x) {
using LDBits = FPBits<long double>;
using StorageType = typename LDBits::StorageType;
@@ -43,21 +43,16 @@ LIBC_INLINE long double sqrt(long double x) {
LDBits bits(x);
- if (bits.is_inf_or_nan()) {
- if (bits.is_neg() && (bits.get_mantissa() == 0)) {
- // sqrt(-Inf) = NaN
- return LDNAN;
- } else {
- // sqrt(NaN) = NaN
- // sqrt(+Inf) = +Inf
- return x;
- }
- } else if (bits.is_zero()) {
+ if (bits == LDBits::inf(Sign::POS) || bits.is_zero() || bits.is_nan()) {
+ // sqrt(+Inf) = +Inf
// sqrt(+0) = +0
// sqrt(-0) = -0
+ // sqrt(NaN) = NaN
+ // sqrt(-NaN) = -NaN
return x;
} else if (bits.is_neg()) {
- // sqrt( negative numbers ) = NaN
+ // sqrt(-Inf) = NaN
+ // sqrt(-x) = NaN
return LDNAN;
} else {
int x_exp = bits.get_explicit_exponent();
@@ -135,7 +130,7 @@ LIBC_INLINE long double sqrt(long double x) {
return out.get_val();
}
}
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
} // namespace x86
} // namespace fputil
diff --git a/src/__support/FPUtil/gpu/FMA.h b/src/__support/FPUtil/gpu/FMA.h
index 86bc86031496..ef1cd26a72dd 100644
--- a/src/__support/FPUtil/gpu/FMA.h
+++ b/src/__support/FPUtil/gpu/FMA.h
@@ -10,12 +10,12 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GPU_FMA_H
#include "src/__support/CPP/type_traits.h"
-#include "src/__support/macros/config.h"
-// These intrinsics map to the FMA instrunctions in the target ISA for the GPU.
+// These intrinsics map to the FMA instructions in the target ISA for the GPU.
// The default rounding mode generated from these will be to the nearest even.
-static_assert(LIBC_HAS_BUILTIN(__builtin_fma), "FMA builtins must be defined");
-static_assert(LIBC_HAS_BUILTIN(__builtin_fmaf), "FMA builtins must be defined");
+#if !__has_builtin(__builtin_fma) || !__has_builtin(__builtin_fmaf)
+#error "FMA builtins must be defined");
+#endif
namespace LIBC_NAMESPACE {
namespace fputil {
diff --git a/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h b/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
new file mode 100644
index 000000000000..1bc849500be0
--- /dev/null
+++ b/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
@@ -0,0 +1,60 @@
+//===-- nextupdown implementation for x86 long double numbers ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/properties/architectures.h"
+
+#if !defined(LIBC_TARGET_ARCH_IS_X86)
+#error "Invalid include"
+#endif
+
+namespace LIBC_NAMESPACE::fputil {
+
+template <bool IsDown>
+LIBC_INLINE constexpr long double nextupdown(long double x) {
+ constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS;
+
+ using FPBits_t = FPBits<long double>;
+ FPBits_t xbits(x);
+ if (xbits.is_nan() || xbits == FPBits_t::max_normal(sign) ||
+ xbits == FPBits_t::inf(sign))
+ return x;
+
+ if (x == 0.0l)
+ return FPBits_t::min_subnormal(sign).get_val();
+
+ using StorageType = typename FPBits_t::StorageType;
+
+ if (xbits.sign() == sign) {
+ if (xbits.get_mantissa() == FPBits_t::FRACTION_MASK) {
+ xbits.set_mantissa(0);
+ xbits.set_biased_exponent(xbits.get_biased_exponent() + 1);
+ } else {
+ xbits = FPBits_t(StorageType(xbits.uintval() + 1));
+ }
+
+ return xbits.get_val();
+ }
+
+ if (xbits.get_mantissa() == 0) {
+ xbits.set_mantissa(FPBits_t::FRACTION_MASK);
+ xbits.set_biased_exponent(xbits.get_biased_exponent() - 1);
+ } else {
+ xbits = FPBits_t(StorageType(xbits.uintval() - 1));
+ }
+
+ return xbits.get_val();
+}
+
+} // namespace LIBC_NAMESPACE::fputil
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
diff --git a/src/__support/FPUtil/x86_64/sqrt.h b/src/__support/FPUtil/x86_64/sqrt.h
index cf3eb9b2f494..93ba8c0b33fd 100644
--- a/src/__support/FPUtil/x86_64/sqrt.h
+++ b/src/__support/FPUtil/x86_64/sqrt.h
@@ -33,7 +33,7 @@ template <> LIBC_INLINE double sqrt<double>(double x) {
return result;
}
-#ifdef LIBC_LONG_DOUBLE_IS_FLOAT64
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
template <> LIBC_INLINE long double sqrt<long double>(long double x) {
long double result;
__asm__ __volatile__("sqrtsd %x1, %x0" : "=x"(result) : "x"(x));
diff --git a/src/__support/File/file.h b/src/__support/File/file.h
index 2ea3843749ff..eafd3ab7d910 100644
--- a/src/__support/File/file.h
+++ b/src/__support/File/file.h
@@ -76,7 +76,7 @@ public:
private:
enum class FileOp : uint8_t { NONE, READ, WRITE, SEEK };
- // Platfrom specific functions which create new file objects should initialize
+ // Platform specific functions which create new file objects should initialize
// these fields suitably via the constructor. Typically, they should be simple
// syscall wrappers for the corresponding functionality.
WriteFunc *platform_write;
@@ -299,7 +299,7 @@ private:
}
};
-// The implementaiton of this function is provided by the platfrom_file
+// The implementaiton of this function is provided by the platform_file
// library.
ErrorOr<File *> openfile(const char *path, const char *mode);
diff --git a/src/__support/GPU/allocator.cpp b/src/__support/GPU/allocator.cpp
new file mode 100644
index 000000000000..a049959964cf
--- /dev/null
+++ b/src/__support/GPU/allocator.cpp
@@ -0,0 +1,45 @@
+//===-- GPU memory allocator implementation ---------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "allocator.h"
+
+#include "src/__support/GPU/utils.h"
+#include "src/__support/RPC/rpc_client.h"
+
+namespace LIBC_NAMESPACE {
+namespace {
+
+void *rpc_allocate(uint64_t size) {
+ void *ptr = nullptr;
+ rpc::Client::Port port = rpc::client.open<RPC_MALLOC>();
+ port.send_and_recv([=](rpc::Buffer *buffer) { buffer->data[0] = size; },
+ [&](rpc::Buffer *buffer) {
+ ptr = reinterpret_cast<void *>(buffer->data[0]);
+ });
+ port.close();
+ return ptr;
+}
+
+void rpc_free(void *ptr) {
+ rpc::Client::Port port = rpc::client.open<RPC_FREE>();
+ port.send([=](rpc::Buffer *buffer) {
+ buffer->data[0] = reinterpret_cast<uintptr_t>(ptr);
+ });
+ port.close();
+}
+
+} // namespace
+
+namespace gpu {
+
+void *allocate(uint64_t size) { return rpc_allocate(size); }
+
+void deallocate(void *ptr) { rpc_free(ptr); }
+
+} // namespace gpu
+} // namespace LIBC_NAMESPACE
diff --git a/src/__support/GPU/allocator.h b/src/__support/GPU/allocator.h
new file mode 100644
index 000000000000..99eeb6826cc2
--- /dev/null
+++ b/src/__support/GPU/allocator.h
@@ -0,0 +1,23 @@
+//===-- GPU memory allocator implementation ---------------------*- 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_ALLOCATOR_H
+#define LLVM_LIBC_SRC___SUPPORT_GPU_ALLOCATOR_H
+
+#include <stdint.h>
+
+namespace LIBC_NAMESPACE {
+namespace gpu {
+
+void *allocate(uint64_t size);
+void deallocate(void *ptr);
+
+} // namespace gpu
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_GPU_ALLOCATOR_H
diff --git a/src/__support/GPU/amdgpu/utils.h b/src/__support/GPU/amdgpu/utils.h
index 9f0ff0c717a6..9b520a6bcf38 100644
--- a/src/__support/GPU/amdgpu/utils.h
+++ b/src/__support/GPU/amdgpu/utils.h
@@ -17,9 +17,6 @@
namespace LIBC_NAMESPACE {
namespace gpu {
-/// The number of threads that execute in lock-step in a lane.
-constexpr const uint64_t LANE_SIZE = __AMDGCN_WAVEFRONT_SIZE;
-
/// Type aliases to the address spaces used by the AMDGPU backend.
template <typename T> using Private = [[clang::opencl_private]] T;
template <typename T> using Constant = [[clang::opencl_constant]] T;
@@ -108,15 +105,15 @@ LIBC_INLINE uint64_t get_thread_id() {
get_num_threads_x() * get_num_threads_y() * get_thread_id_z();
}
-/// Returns the size of an AMD wavefront. Either 32 or 64 depending on hardware.
-LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
+/// Returns the size of an AMD wavefront, either 32 or 64 depending on hardware
+/// and compilation options.
+LIBC_INLINE uint32_t get_lane_size() {
+ return __builtin_amdgcn_wavefrontsize();
+}
/// Returns the id of the thread inside of an AMD wavefront executing together.
[[clang::convergent]] LIBC_INLINE uint32_t get_lane_id() {
- if constexpr (LANE_SIZE == 64)
- return __builtin_amdgcn_mbcnt_hi(~0u, __builtin_amdgcn_mbcnt_lo(~0u, 0u));
- else
- return __builtin_amdgcn_mbcnt_lo(~0u, 0u);
+ return __builtin_amdgcn_mbcnt_hi(~0u, __builtin_amdgcn_mbcnt_lo(~0u, 0u));
}
/// Returns the bit-mask of active threads in the current wavefront.
@@ -134,11 +131,7 @@ LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
[[clang::convergent]] LIBC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) {
// the lane_mask & gives the nvptx semantics when lane_mask is a subset of
// the active threads
- if constexpr (LANE_SIZE == 64) {
- return lane_mask & __builtin_amdgcn_ballot_w64(x);
- } else {
- return lane_mask & __builtin_amdgcn_ballot_w32(x);
- }
+ return lane_mask & __builtin_amdgcn_ballot_w64(x);
}
/// Waits for all the threads in the block to converge and issues a fence.
@@ -152,33 +145,33 @@ LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
__builtin_amdgcn_wave_barrier();
}
-/// Returns the current value of the GPU's processor clock.
-/// NOTE: The RDNA3 and RDNA2 architectures use a 20-bit cycle cycle counter.
-LIBC_INLINE uint64_t processor_clock() {
- if constexpr (LIBC_HAS_BUILTIN(__builtin_amdgcn_s_memtime))
- return __builtin_amdgcn_s_memtime();
- else if constexpr (LIBC_HAS_BUILTIN(__builtin_readcyclecounter))
- return __builtin_readcyclecounter();
- else
- return 0;
+/// Shuffles the the lanes inside the wavefront according to the given index.
+[[clang::convergent]] LIBC_INLINE uint32_t shuffle(uint64_t, uint32_t idx,
+ uint32_t x) {
+ return __builtin_amdgcn_ds_bpermute(idx << 2, x);
}
+/// Returns the current value of the GPU's processor clock.
+/// NOTE: The RDNA3 and RDNA2 architectures use a 20-bit cycle counter.
+LIBC_INLINE uint64_t processor_clock() { return __builtin_readcyclecounter(); }
+
/// Returns a fixed-frequency timestamp. The actual frequency is dependent on
/// the card and can only be queried via the driver.
LIBC_INLINE uint64_t fixed_frequency_clock() {
- if constexpr (LIBC_HAS_BUILTIN(__builtin_amdgcn_s_sendmsg_rtnl))
- return __builtin_amdgcn_s_sendmsg_rtnl(0x83);
- else if constexpr (LIBC_HAS_BUILTIN(__builtin_amdgcn_s_memrealtime))
- return __builtin_amdgcn_s_memrealtime();
- else if constexpr (LIBC_HAS_BUILTIN(__builtin_amdgcn_s_memtime))
- return __builtin_amdgcn_s_memtime();
- else
- return 0;
+ return __builtin_readsteadycounter();
}
/// Terminates execution of the associated wavefront.
[[noreturn]] LIBC_INLINE void end_program() { __builtin_amdgcn_endpgm(); }
+/// Returns a unique identifier for the process cluster the current wavefront is
+/// executing on. Here we use the identifier for the compute unit (CU) and
+/// shader engine.
+/// FIXME: Currently unimplemented on AMDGPU until we have a simpler interface
+/// than the one at
+/// https://github.com/ROCm/clr/blob/develop/hipamd/include/hip/amd_detail/amd_device_functions.h#L899
+LIBC_INLINE uint32_t get_cluster_id() { return 0; }
+
} // namespace gpu
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/GPU/generic/utils.h b/src/__support/GPU/generic/utils.h
index b701db482bbe..b6df59f7aa9e 100644
--- a/src/__support/GPU/generic/utils.h
+++ b/src/__support/GPU/generic/utils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_GENERIC_IO_H
-#define LLVM_LIBC_SRC___SUPPORT_GPU_GENERIC_IO_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_GENERIC_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_GPU_GENERIC_UTILS_H
#include "src/__support/common.h"
@@ -16,8 +16,6 @@
namespace LIBC_NAMESPACE {
namespace gpu {
-constexpr const uint64_t LANE_SIZE = 1;
-
template <typename T> using Private = T;
template <typename T> using Constant = T;
template <typename T> using Shared = T;
@@ -55,7 +53,7 @@ LIBC_INLINE uint32_t get_thread_id_z() { return 0; }
LIBC_INLINE uint64_t get_thread_id() { return 0; }
-LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
+LIBC_INLINE uint32_t get_lane_size() { return 1; }
LIBC_INLINE uint32_t get_lane_id() { return 0; }
@@ -69,13 +67,17 @@ LIBC_INLINE void sync_threads() {}
LIBC_INLINE void sync_lane(uint64_t) {}
+LIBC_INLINE uint32_t shuffle(uint64_t, uint32_t, uint32_t x) { return x; }
+
LIBC_INLINE uint64_t processor_clock() { return 0; }
LIBC_INLINE uint64_t fixed_frequency_clock() { return 0; }
[[noreturn]] LIBC_INLINE void end_program() { __builtin_unreachable(); }
+LIBC_INLINE uint32_t get_cluster_id() { return 0; }
+
} // namespace gpu
} // namespace LIBC_NAMESPACE
-#endif
+#endif // LLVM_LIBC_SRC___SUPPORT_GPU_GENERIC_UTILS_H
diff --git a/src/__support/GPU/nvptx/utils.h b/src/__support/GPU/nvptx/utils.h
index 9fe3caa49147..3f19afb83648 100644
--- a/src/__support/GPU/nvptx/utils.h
+++ b/src/__support/GPU/nvptx/utils.h
@@ -16,9 +16,6 @@
namespace LIBC_NAMESPACE {
namespace gpu {
-/// The number of threads that execute in lock-step in a warp.
-constexpr const uint64_t LANE_SIZE = 32;
-
/// Type aliases to the address spaces used by the NVPTX backend.
template <typename T> using Private = [[clang::opencl_private]] T;
template <typename T> using Constant = [[clang::opencl_constant]] T;
@@ -95,12 +92,12 @@ LIBC_INLINE uint64_t get_thread_id() {
get_num_threads_x() * get_num_threads_y() * get_thread_id_z();
}
-/// Returns the size of a CUDA warp.
-LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
+/// Returns the size of a CUDA warp, always 32 on NVIDIA hardware.
+LIBC_INLINE uint32_t get_lane_size() { return 32; }
/// Returns the id of the thread inside of a CUDA warp executing together.
[[clang::convergent]] LIBC_INLINE uint32_t get_lane_id() {
- return get_thread_id() & (get_lane_size() - 1);
+ return __nvvm_read_ptx_sreg_laneid();
}
/// Returns the bit-mask of active threads in the current warp.
@@ -113,21 +110,13 @@ LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
uint32_t x) {
uint32_t mask = static_cast<uint32_t>(lane_mask);
uint32_t id = __builtin_ffs(mask) - 1;
-#if __CUDA_ARCH__ >= 600
return __nvvm_shfl_sync_idx_i32(mask, x, id, get_lane_size() - 1);
-#else
- return __nvvm_shfl_idx_i32(x, id, get_lane_size() - 1);
-#endif
}
/// Returns a bitmask of threads in the current lane for which \p x is true.
[[clang::convergent]] LIBC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) {
uint32_t mask = static_cast<uint32_t>(lane_mask);
-#if __CUDA_ARCH__ >= 600
return __nvvm_vote_ballot_sync(mask, x);
-#else
- return mask & __nvvm_vote_ballot(x);
-#endif
}
/// Waits for all the threads in the block to converge and issues a fence.
[[clang::convergent]] LIBC_INLINE void sync_threads() { __syncthreads(); }
@@ -137,19 +126,29 @@ LIBC_INLINE uint32_t get_lane_size() { return LANE_SIZE; }
__nvvm_bar_warp_sync(static_cast<uint32_t>(mask));
}
-/// Returns the current value of the GPU's processor clock.
-LIBC_INLINE uint64_t processor_clock() {
- return __nvvm_read_ptx_sreg_clock64();
+/// Shuffles the the lanes inside the warp according to the given index.
+[[clang::convergent]] LIBC_INLINE uint32_t shuffle(uint64_t lane_mask,
+ uint32_t idx, uint32_t x) {
+ uint32_t mask = static_cast<uint32_t>(lane_mask);
+ uint32_t bitmask = (mask >> idx) & 1;
+ return -bitmask & __nvvm_shfl_sync_idx_i32(mask, x, idx, get_lane_size() - 1);
}
+/// Returns the current value of the GPU's processor clock.
+LIBC_INLINE uint64_t processor_clock() { return __builtin_readcyclecounter(); }
+
/// Returns a global fixed-frequency timer at nanosecond frequency.
LIBC_INLINE uint64_t fixed_frequency_clock() {
- return __nvvm_read_ptx_sreg_globaltimer();
+ return __builtin_readsteadycounter();
}
/// Terminates execution of the calling thread.
[[noreturn]] LIBC_INLINE void end_program() { __nvvm_exit(); }
+/// Returns a unique identifier for the process cluster the current warp is
+/// executing on. Here we use the identifier for the symmetric multiprocessor.
+LIBC_INLINE uint32_t get_cluster_id() { return __nvvm_read_ptx_sreg_smid(); }
+
} // namespace gpu
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/GPU/utils.h b/src/__support/GPU/utils.h
index 6505b18dbd33..cb04a3562eb1 100644
--- a/src/__support/GPU/utils.h
+++ b/src/__support/GPU/utils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_UTIL_H
-#define LLVM_LIBC_SRC___SUPPORT_GPU_UTIL_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_GPU_UTILS_H
#include "src/__support/macros/properties/architectures.h"
@@ -23,7 +23,7 @@ namespace LIBC_NAMESPACE {
namespace gpu {
/// Get the first active thread inside the lane.
LIBC_INLINE uint64_t get_first_lane_id(uint64_t lane_mask) {
- return __builtin_ffsl(lane_mask) - 1;
+ return __builtin_ffsll(lane_mask) - 1;
}
/// Conditional that is only true for a single thread in a lane.
@@ -31,7 +31,26 @@ LIBC_INLINE bool is_first_lane(uint64_t lane_mask) {
return gpu::get_lane_id() == get_first_lane_id(lane_mask);
}
+/// Gets the sum of all lanes inside the warp or wavefront.
+LIBC_INLINE uint32_t reduce(uint64_t lane_mask, uint32_t x) {
+ for (uint32_t step = gpu::get_lane_size() / 2; step > 0; step /= 2) {
+ uint32_t index = step + gpu::get_lane_id();
+ x += gpu::shuffle(lane_mask, index, x);
+ }
+ return gpu::broadcast_value(lane_mask, x);
+}
+
+/// Gets the accumulator scan of the threads in the warp or wavefront.
+LIBC_INLINE uint32_t scan(uint64_t lane_mask, uint32_t x) {
+ for (uint32_t step = 1; step < gpu::get_lane_size(); step *= 2) {
+ uint32_t index = gpu::get_lane_id() - step;
+ uint32_t bitmask = gpu::get_lane_id() >= step;
+ x += -bitmask & gpu::shuffle(lane_mask, index, x);
+ }
+ return x;
+}
+
} // namespace gpu
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_IO_H
+#endif // LLVM_LIBC_SRC___SUPPORT_GPU_UTILS_H
diff --git a/src/__support/HashTable/table.h b/src/__support/HashTable/table.h
index 5b4697e5245b..8f6c5887c189 100644
--- a/src/__support/HashTable/table.h
+++ b/src/__support/HashTable/table.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_table_H
-#define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_table_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H
+#define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H
#include "include/llvm-libc-types/ENTRY.h"
#include "src/__support/CPP/bit.h" // bit_ceil
@@ -351,4 +351,4 @@ public:
} // namespace internal
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_HASHTABLE_table_H
+#endif // LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H
diff --git a/src/__support/OSUtil/baremetal/io.cpp b/src/__support/OSUtil/baremetal/io.cpp
new file mode 100644
index 000000000000..347c7d405b0a
--- /dev/null
+++ b/src/__support/OSUtil/baremetal/io.cpp
@@ -0,0 +1,22 @@
+//===---------- Baremetal implementation of IO utils ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "io.h"
+
+#include "src/__support/CPP/string_view.h"
+
+// This is intended to be provided by the vendor.
+extern "C" void __llvm_libc_log_write(const char *msg, size_t len);
+
+namespace LIBC_NAMESPACE {
+
+void write_to_stderr(cpp::string_view msg) {
+ __llvm_libc_log_write(msg.data(), msg.size());
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/__support/OSUtil/baremetal/io.h b/src/__support/OSUtil/baremetal/io.h
index a50c11d4aea1..87534641b1fa 100644
--- a/src/__support/OSUtil/baremetal/io.h
+++ b/src/__support/OSUtil/baremetal/io.h
@@ -13,12 +13,7 @@
namespace LIBC_NAMESPACE {
-// This is intended to be provided by the vendor.
-extern "C" void __llvm_libc_log_write(const char *msg, size_t len);
-
-void write_to_stderr(cpp::string_view msg) {
- __llvm_libc_log_write(msg.data(), msg.size());
-}
+void write_to_stderr(cpp::string_view msg);
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/OSUtil/baremetal/quick_exit.h b/src/__support/OSUtil/baremetal/quick_exit.cpp
index 74f9142e21b8..5b6fcf42341e 100644
--- a/src/__support/OSUtil/baremetal/quick_exit.h
+++ b/src/__support/OSUtil/baremetal/quick_exit.cpp
@@ -6,16 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_QUICK_EXIT_H
-
-namespace LIBC_NAMESPACE {
+#include "src/__support/OSUtil/quick_exit.h"
// This is intended to be provided by the vendor.
-extern "C" void __llvm_libc_quick_exit(int status);
+extern "C" [[noreturn]] void __llvm_libc_quick_exit(int status);
-void quick_exit(int status) { __llvm_libc_quick_exit(status); }
+namespace LIBC_NAMESPACE {
-} // namespace LIBC_NAMESPACE
+[[noreturn]] void quick_exit(int status) { __llvm_libc_quick_exit(status); }
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_QUICK_EXIT_H
+} // namespace LIBC_NAMESPACE
diff --git a/src/__support/OSUtil/darwin/quick_exit.h b/src/__support/OSUtil/darwin/quick_exit.h
deleted file mode 100644
index 71647f50def5..000000000000
--- a/src/__support/OSUtil/darwin/quick_exit.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===--------- Darwin implementation of a quick exit function ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_QUICK_EXIT_H
-
-#include "syscall.h" // For internal syscall function.
-
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LIBC_INLINE void quick_exit(int status) {
- for (;;) {
- LIBC_NAMESPACE::syscall_impl<long>(1 /* SYS_exit */, status);
- }
-}
-
-} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_QUICK_EXIT_H
diff --git a/src/__support/OSUtil/gpu/io.h b/src/__support/OSUtil/gpu/io.h
index d6c89cf45e3a..e5562eb74a67 100644
--- a/src/__support/OSUtil/gpu/io.h
+++ b/src/__support/OSUtil/gpu/io.h
@@ -18,4 +18,4 @@ void write_to_stderr(cpp::string_view msg);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_IO_H
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_IO_H
diff --git a/src/__support/OSUtil/gpu/quick_exit.cpp b/src/__support/OSUtil/gpu/quick_exit.cpp
index 1a03be0ace67..af4795905e78 100644
--- a/src/__support/OSUtil/gpu/quick_exit.cpp
+++ b/src/__support/OSUtil/gpu/quick_exit.cpp
@@ -6,17 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
-
-#include "quick_exit.h"
+#include "src/__support/OSUtil/quick_exit.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
-void quick_exit(int status) {
+[[noreturn]] void quick_exit(int status) {
// We want to first make sure the server is listening before we exit.
rpc::Client::Port port = rpc::client.open<RPC_EXIT>();
port.send_and_recv([](rpc::Buffer *) {}, [](rpc::Buffer *) {});
@@ -29,5 +26,3 @@ void quick_exit(int status) {
}
} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
diff --git a/src/__support/OSUtil/linux/quick_exit.h b/src/__support/OSUtil/linux/quick_exit.cpp
index 432395584d84..51b3231d389f 100644
--- a/src/__support/OSUtil/linux/quick_exit.h
+++ b/src/__support/OSUtil/linux/quick_exit.cpp
@@ -6,13 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H
-
-#include "syscall.h" // For internal syscall function.
-
#include "src/__support/common.h"
-
+#include "syscall.h" // For internal syscall function.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE {
@@ -22,7 +17,7 @@ namespace LIBC_NAMESPACE {
#ifdef LIBC_TARGET_ARCH_IS_X86
__attribute__((no_stack_protector))
#endif
-LIBC_INLINE void
+__attribute__((noreturn)) void
quick_exit(int status) {
for (;;) {
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit_group, status);
@@ -31,5 +26,3 @@ quick_exit(int status) {
}
} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H
diff --git a/src/__support/OSUtil/quick_exit.h b/src/__support/OSUtil/quick_exit.h
index 6c59c1afcda2..e445917059c3 100644
--- a/src/__support/OSUtil/quick_exit.h
+++ b/src/__support/OSUtil/quick_exit.h
@@ -9,17 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H
-#include "src/__support/macros/properties/architectures.h"
+namespace LIBC_NAMESPACE {
-#if defined(LIBC_TARGET_ARCH_IS_GPU)
-#include "gpu/quick_exit.h"
-#elif defined(__APPLE__)
-#include "darwin/quick_exit.h"
-#elif defined(__linux__)
-#include "linux/quick_exit.h"
-#elif defined(__ELF__)
-// TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL.
-#include "baremetal/quick_exit.h"
-#endif
+[[noreturn]] void quick_exit(int status);
+
+}
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H
diff --git a/src/__support/RPC/rpc.h b/src/__support/RPC/rpc.h
index 7b2c89ac4dce..05506c04fc07 100644
--- a/src/__support/RPC/rpc.h
+++ b/src/__support/RPC/rpc.h
@@ -43,21 +43,8 @@ struct Header {
uint16_t opcode;
};
-/// The data payload for the associated packet. We provide enough space for each
-/// thread in the cooperating lane to have a buffer.
-template <uint32_t lane_size = gpu::LANE_SIZE> struct Payload {
- Buffer slot[lane_size];
-};
-
-/// A packet used to share data between the client and server across an entire
-/// lane. We use a lane as the minimum granularity for execution.
-template <uint32_t lane_size = gpu::LANE_SIZE> struct alignas(64) Packet {
- Header header;
- Payload<lane_size> payload;
-};
-
/// The maximum number of parallel ports that the RPC interface can support.
-constexpr uint64_t MAX_PORT_COUNT = 512;
+constexpr uint64_t MAX_PORT_COUNT = 4096;
/// A common process used to synchronize communication between a client and a
/// server. The process contains a read-only inbox and a write-only outbox used
@@ -71,7 +58,7 @@ constexpr uint64_t MAX_PORT_COUNT = 512;
/// - The client will always start with a 'send' operation.
/// - The server will always start with a 'recv' operation.
/// - Every 'send' or 'recv' call is mirrored by the other process.
-template <bool Invert, typename Packet> struct Process {
+template <bool Invert> struct Process {
LIBC_INLINE Process() = default;
LIBC_INLINE Process(const Process &) = delete;
LIBC_INLINE Process &operator=(const Process &) = delete;
@@ -82,7 +69,8 @@ template <bool Invert, typename Packet> struct Process {
uint32_t port_count = 0;
cpp::Atomic<uint32_t> *inbox = nullptr;
cpp::Atomic<uint32_t> *outbox = nullptr;
- Packet *packet = nullptr;
+ Header *header = nullptr;
+ Buffer *packet = nullptr;
static constexpr uint64_t NUM_BITS_IN_WORD = sizeof(uint32_t) * 8;
cpp::Atomic<uint32_t> lock[MAX_PORT_COUNT / NUM_BITS_IN_WORD] = {0};
@@ -92,7 +80,9 @@ template <bool Invert, typename Packet> struct Process {
advance(buffer, inbox_offset(port_count)))),
outbox(reinterpret_cast<cpp::Atomic<uint32_t> *>(
advance(buffer, outbox_offset(port_count)))),
- packet(reinterpret_cast<Packet *>(
+ header(reinterpret_cast<Header *>(
+ advance(buffer, header_offset(port_count)))),
+ packet(reinterpret_cast<Buffer *>(
advance(buffer, buffer_offset(port_count)))) {}
/// Allocate a memory buffer sufficient to store the following equivalent
@@ -101,10 +91,12 @@ template <bool Invert, typename Packet> struct Process {
/// struct Equivalent {
/// Atomic<uint32_t> primary[port_count];
/// Atomic<uint32_t> secondary[port_count];
- /// Packet buffer[port_count];
+ /// Header header[port_count];
+ /// Buffer packet[port_count][lane_size];
/// };
- LIBC_INLINE static constexpr uint64_t allocation_size(uint32_t port_count) {
- return buffer_offset(port_count) + buffer_bytes(port_count);
+ LIBC_INLINE static constexpr uint64_t allocation_size(uint32_t port_count,
+ uint32_t lane_size) {
+ return buffer_offset(port_count) + buffer_bytes(port_count, lane_size);
}
/// Retrieve the inbox state from memory shared between processes.
@@ -144,6 +136,13 @@ template <bool Invert, typename Packet> struct Process {
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
}
+ /// The packet is a linearly allocated array of buffers used to communicate
+ /// with the other process. This function returns the appropriate slot in this
+ /// array such that the process can operate on an entire warp or wavefront.
+ LIBC_INLINE Buffer *get_packet(uint32_t index, uint32_t lane_size) {
+ return &packet[index * lane_size];
+ }
+
/// Determines if this process needs to wait for ownership of the buffer. We
/// invert the condition on one of the processes to indicate that if one
/// process owns the buffer then the other does not.
@@ -199,12 +198,9 @@ template <bool Invert, typename Packet> struct Process {
/// convergent, otherwise the compiler will sink the store and deadlock.
[[clang::convergent]] LIBC_INLINE void unlock(uint64_t lane_mask,
uint32_t index) {
- // Do not move any writes past the unlock
+ // Do not move any writes past the unlock.
atomic_thread_fence(cpp::MemoryOrder::RELEASE);
- // Wait for other threads in the warp to finish using the lock
- gpu::sync_lane(lane_mask);
-
// Use exactly one thread to clear the nth bit in the lock array Must
// restrict to a single thread to avoid one thread dropping the lock, then
// an unrelated warp claiming the lock, then a second thread in this warp
@@ -219,8 +215,9 @@ template <bool Invert, typename Packet> struct Process {
}
/// Number of bytes to allocate for the buffer containing the packets.
- LIBC_INLINE static constexpr uint64_t buffer_bytes(uint32_t port_count) {
- return port_count * sizeof(Packet);
+ LIBC_INLINE static constexpr uint64_t buffer_bytes(uint32_t port_count,
+ uint32_t lane_size) {
+ return port_count * lane_size * sizeof(Buffer);
}
/// Offset of the inbox in memory. This is the same as the outbox if inverted.
@@ -234,8 +231,14 @@ template <bool Invert, typename Packet> struct Process {
}
/// Offset of the buffer containing the packets after the inbox and outbox.
+ LIBC_INLINE static constexpr uint64_t header_offset(uint32_t port_count) {
+ return align_up(2 * mailbox_bytes(port_count), alignof(Header));
+ }
+
+ /// Offset of the buffer containing the packets after the inbox and outbox.
LIBC_INLINE static constexpr uint64_t buffer_offset(uint32_t port_count) {
- return align_up(2 * mailbox_bytes(port_count), alignof(Packet));
+ return align_up(header_offset(port_count) + port_count * sizeof(Header),
+ alignof(Buffer));
}
/// Conditionally set the n-th bit in the atomic bitfield.
@@ -262,39 +265,39 @@ template <bool Invert, typename Packet> struct Process {
};
/// Invokes a function accross every active buffer across the total lane size.
-template <uint32_t lane_size>
static LIBC_INLINE void invoke_rpc(cpp::function<void(Buffer *)> fn,
- Packet<lane_size> &packet) {
+ uint32_t lane_size, uint64_t lane_mask,
+ Buffer *slot) {
if constexpr (is_process_gpu()) {
- fn(&packet.payload.slot[gpu::get_lane_id()]);
+ fn(&slot[gpu::get_lane_id()]);
} else {
for (uint32_t i = 0; i < lane_size; i += gpu::get_lane_size())
- if (packet.header.mask & 1ul << i)
- fn(&packet.payload.slot[i]);
+ if (lane_mask & (1ul << i))
+ fn(&slot[i]);
}
}
/// Alternate version that also provides the index of the current lane.
-template <uint32_t lane_size>
static LIBC_INLINE void invoke_rpc(cpp::function<void(Buffer *, uint32_t)> fn,
- Packet<lane_size> &packet) {
+ uint32_t lane_size, uint64_t lane_mask,
+ Buffer *slot) {
if constexpr (is_process_gpu()) {
- fn(&packet.payload.slot[gpu::get_lane_id()], gpu::get_lane_id());
+ fn(&slot[gpu::get_lane_id()], gpu::get_lane_id());
} else {
for (uint32_t i = 0; i < lane_size; i += gpu::get_lane_size())
- if (packet.header.mask & 1ul << i)
- fn(&packet.payload.slot[i], i);
+ if (lane_mask & (1ul << i))
+ fn(&slot[i], i);
}
}
/// The port provides the interface to communicate between the multiple
/// processes. A port is conceptually an index into the memory provided by the
/// underlying process that is guarded by a lock bit.
-template <bool T, typename S> struct Port {
- LIBC_INLINE Port(Process<T, S> &process, uint64_t lane_mask, uint32_t index,
- uint32_t out)
- : process(process), lane_mask(lane_mask), index(index), out(out),
- receive(false), owns_buffer(true) {}
+template <bool T> struct Port {
+ LIBC_INLINE Port(Process<T> &process, uint64_t lane_mask, uint32_t lane_size,
+ uint32_t index, uint32_t out)
+ : process(process), lane_mask(lane_mask), lane_size(lane_size),
+ index(index), out(out), receive(false), owns_buffer(true) {}
LIBC_INLINE ~Port() = default;
private:
@@ -304,8 +307,8 @@ private:
LIBC_INLINE Port &operator=(Port &&) = default;
friend struct Client;
- template <uint32_t U> friend struct Server;
- friend class cpp::optional<Port<T, S>>;
+ friend struct Server;
+ friend class cpp::optional<Port<T>>;
public:
template <typename U> LIBC_INLINE void recv(U use);
@@ -319,12 +322,15 @@ public:
LIBC_INLINE void recv_n(void **dst, uint64_t *size, A &&alloc);
LIBC_INLINE uint16_t get_opcode() const {
- return process.packet[index].header.opcode;
+ return process.header[index].opcode;
}
LIBC_INLINE uint16_t get_index() const { return index; }
LIBC_INLINE void close() {
+ // Wait for all lanes to finish using the port.
+ gpu::sync_lane(lane_mask);
+
// The server is passive, if it own the buffer when it closes we need to
// give ownership back to the client.
if (owns_buffer && T)
@@ -333,8 +339,9 @@ public:
}
private:
- Process<T, S> &process;
+ Process<T> &process;
uint64_t lane_mask;
+ uint32_t lane_size;
uint32_t index;
uint32_t out;
bool receive;
@@ -351,19 +358,18 @@ struct Client {
LIBC_INLINE Client(uint32_t port_count, void *buffer)
: process(port_count, buffer) {}
- using Port = rpc::Port<false, Packet<gpu::LANE_SIZE>>;
+ using Port = rpc::Port<false>;
template <uint16_t opcode> LIBC_INLINE Port open();
private:
- Process<false, Packet<gpu::LANE_SIZE>> process;
+ Process<false> process;
};
static_assert(cpp::is_trivially_copyable<Client>::value &&
- sizeof(Process<false, Packet<1>>) ==
- sizeof(Process<false, Packet<32>>),
+ sizeof(Process<true>) == sizeof(Process<false>),
"The client is not trivially copyable from the server");
/// The RPC server used to respond to the client.
-template <uint32_t lane_size> struct Server {
+struct Server {
LIBC_INLINE Server() = default;
LIBC_INLINE Server(const Server &) = delete;
LIBC_INLINE Server &operator=(const Server &) = delete;
@@ -372,38 +378,37 @@ template <uint32_t lane_size> struct Server {
LIBC_INLINE Server(uint32_t port_count, void *buffer)
: process(port_count, buffer) {}
- using Port = rpc::Port<true, Packet<lane_size>>;
- LIBC_INLINE cpp::optional<Port> try_open(uint32_t start = 0);
- LIBC_INLINE Port open();
+ using Port = rpc::Port<true>;
+ LIBC_INLINE cpp::optional<Port> try_open(uint32_t lane_size,
+ uint32_t start = 0);
+ LIBC_INLINE Port open(uint32_t lane_size);
- LIBC_INLINE static uint64_t allocation_size(uint32_t port_count) {
- return Process<true, Packet<lane_size>>::allocation_size(port_count);
+ LIBC_INLINE static uint64_t allocation_size(uint32_t lane_size,
+ uint32_t port_count) {
+ return Process<true>::allocation_size(port_count, lane_size);
}
private:
- Process<true, Packet<lane_size>> process;
+ Process<true> process;
};
/// Applies \p fill to the shared buffer and initiates a send operation.
-template <bool T, typename S>
-template <typename F>
-LIBC_INLINE void Port<T, S>::send(F fill) {
+template <bool T> template <typename F> LIBC_INLINE void Port<T>::send(F fill) {
uint32_t in = owns_buffer ? out ^ T : process.load_inbox(lane_mask, index);
// We need to wait until we own the buffer before sending.
process.wait_for_ownership(lane_mask, index, out, in);
// Apply the \p fill function to initialize the buffer and release the memory.
- invoke_rpc(fill, process.packet[index]);
+ invoke_rpc(fill, lane_size, process.header[index].mask,
+ process.get_packet(index, lane_size));
out = process.invert_outbox(index, out);
owns_buffer = false;
receive = false;
}
/// Applies \p use to the shared buffer and acknowledges the send.
-template <bool T, typename S>
-template <typename U>
-LIBC_INLINE void Port<T, S>::recv(U use) {
+template <bool T> template <typename U> LIBC_INLINE void Port<T>::recv(U use) {
// We only exchange ownership of the buffer during a receive if we are waiting
// for a previous receive to finish.
if (receive) {
@@ -417,15 +422,16 @@ LIBC_INLINE void Port<T, S>::recv(U use) {
process.wait_for_ownership(lane_mask, index, out, in);
// Apply the \p use function to read the memory out of the buffer.
- invoke_rpc(use, process.packet[index]);
+ invoke_rpc(use, lane_size, process.header[index].mask,
+ process.get_packet(index, lane_size));
receive = true;
owns_buffer = true;
}
/// Combines a send and receive into a single function.
-template <bool T, typename S>
+template <bool T>
template <typename F, typename U>
-LIBC_INLINE void Port<T, S>::send_and_recv(F fill, U use) {
+LIBC_INLINE void Port<T>::send_and_recv(F fill, U use) {
send(fill);
recv(use);
}
@@ -433,17 +439,17 @@ LIBC_INLINE void Port<T, S>::send_and_recv(F fill, U use) {
/// Combines a receive and send operation into a single function. The \p work
/// function modifies the buffer in-place and the send is only used to initiate
/// the copy back.
-template <bool T, typename S>
+template <bool T>
template <typename W>
-LIBC_INLINE void Port<T, S>::recv_and_send(W work) {
+LIBC_INLINE void Port<T>::recv_and_send(W work) {
recv(work);
send([](Buffer *) { /* no-op */ });
}
/// Helper routine to simplify the interface when sending from the GPU using
/// thread private pointers to the underlying value.
-template <bool T, typename S>
-LIBC_INLINE void Port<T, S>::send_n(const void *src, uint64_t size) {
+template <bool T>
+LIBC_INLINE void Port<T>::send_n(const void *src, uint64_t size) {
const void **src_ptr = &src;
uint64_t *size_ptr = &size;
send_n(src_ptr, size_ptr);
@@ -451,8 +457,8 @@ LIBC_INLINE void Port<T, S>::send_n(const void *src, uint64_t size) {
/// Sends an arbitrarily sized data buffer \p src across the shared channel in
/// multiples of the packet length.
-template <bool T, typename S>
-LIBC_INLINE void Port<T, S>::send_n(const void *const *src, uint64_t *size) {
+template <bool T>
+LIBC_INLINE void Port<T>::send_n(const void *const *src, uint64_t *size) {
uint64_t num_sends = 0;
send([&](Buffer *buffer, uint32_t id) {
reinterpret_cast<uint64_t *>(buffer->data)[0] = lane_value(size, id);
@@ -465,7 +471,7 @@ LIBC_INLINE void Port<T, S>::send_n(const void *const *src, uint64_t *size) {
rpc_memcpy(&buffer->data[1], lane_value(src, id), len);
});
uint64_t idx = sizeof(Buffer::data) - sizeof(uint64_t);
- uint64_t mask = process.packet[index].header.mask;
+ uint64_t mask = process.header[index].mask;
while (gpu::ballot(mask, idx < num_sends)) {
send([=](Buffer *buffer, uint32_t id) {
uint64_t len = lane_value(size, id) - idx > sizeof(Buffer::data)
@@ -481,9 +487,9 @@ LIBC_INLINE void Port<T, S>::send_n(const void *const *src, uint64_t *size) {
/// Receives an arbitrarily sized data buffer across the shared channel in
/// multiples of the packet length. The \p alloc function is called with the
/// size of the data so that we can initialize the size of the \p dst buffer.
-template <bool T, typename S>
+template <bool T>
template <typename A>
-LIBC_INLINE void Port<T, S>::recv_n(void **dst, uint64_t *size, A &&alloc) {
+LIBC_INLINE void Port<T>::recv_n(void **dst, uint64_t *size, A &&alloc) {
uint64_t num_recvs = 0;
recv([&](Buffer *buffer, uint32_t id) {
lane_value(size, id) = reinterpret_cast<uint64_t *>(buffer->data)[0];
@@ -498,7 +504,7 @@ LIBC_INLINE void Port<T, S>::recv_n(void **dst, uint64_t *size, A &&alloc) {
rpc_memcpy(lane_value(dst, id), &buffer->data[1], len);
});
uint64_t idx = sizeof(Buffer::data) - sizeof(uint64_t);
- uint64_t mask = process.packet[index].header.mask;
+ uint64_t mask = process.header[index].mask;
while (gpu::ballot(mask, idx < num_recvs)) {
recv([=](Buffer *buffer, uint32_t id) {
uint64_t len = lane_value(size, id) - idx > sizeof(Buffer::data)
@@ -515,11 +521,13 @@ LIBC_INLINE void Port<T, S>::recv_n(void **dst, uint64_t *size, A &&alloc) {
/// only open a port if we find an index that is in a valid sending state. That
/// is, there are send operations pending that haven't been serviced on this
/// port. Each port instance uses an associated \p opcode to tell the server
-/// what to do.
-template <uint16_t opcode> LIBC_INLINE Client::Port Client::open() {
+/// what to do. The Client interface provides the appropriate lane size to the
+/// port using the platform's returned value.
+template <uint16_t opcode>
+[[clang::convergent]] LIBC_INLINE Client::Port Client::open() {
// Repeatedly perform a naive linear scan for a port that can be opened to
// send data.
- for (uint32_t index = 0;; ++index) {
+ for (uint32_t index = gpu::get_cluster_id();; ++index) {
// Start from the beginning if we run out of ports to check.
if (index >= process.port_count)
index = 0;
@@ -540,20 +548,18 @@ template <uint16_t opcode> LIBC_INLINE Client::Port Client::open() {
}
if (gpu::is_first_lane(lane_mask)) {
- process.packet[index].header.opcode = opcode;
- process.packet[index].header.mask = lane_mask;
+ process.header[index].opcode = opcode;
+ process.header[index].mask = lane_mask;
}
gpu::sync_lane(lane_mask);
- return Port(process, lane_mask, index, out);
+ return Port(process, lane_mask, gpu::get_lane_size(), index, out);
}
}
/// Attempts to open a port to use as the server. The server can only open a
/// port if it has a pending receive operation
-template <uint32_t lane_size>
-[[clang::convergent]] LIBC_INLINE
- cpp::optional<typename Server<lane_size>::Port>
- Server<lane_size>::try_open(uint32_t start) {
+[[clang::convergent]] LIBC_INLINE cpp::optional<typename Server::Port>
+Server::try_open(uint32_t lane_size, uint32_t start) {
// 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 = gpu::get_lane_mask();
@@ -577,15 +583,14 @@ template <uint32_t lane_size>
continue;
}
- return Port(process, lane_mask, index, out);
+ return Port(process, lane_mask, lane_size, index, out);
}
return cpp::nullopt;
}
-template <uint32_t lane_size>
-LIBC_INLINE typename Server<lane_size>::Port Server<lane_size>::open() {
+LIBC_INLINE Server::Port Server::open(uint32_t lane_size) {
for (;;) {
- if (cpp::optional<Server::Port> p = try_open())
+ if (cpp::optional<Server::Port> p = try_open(lane_size))
return cpp::move(p.value());
sleep_briefly();
}
diff --git a/src/__support/RPC/rpc_client.h b/src/__support/RPC/rpc_client.h
index 571d7cce2a80..6e1827dbfeea 100644
--- a/src/__support/RPC/rpc_client.h
+++ b/src/__support/RPC/rpc_client.h
@@ -11,7 +11,7 @@
#include "rpc.h"
-#include "llvm-libc-types/rpc_opcodes_t.h"
+#include "include/llvm-libc-types/rpc_opcodes_t.h"
namespace LIBC_NAMESPACE {
namespace rpc {
diff --git a/src/__support/RPC/rpc_util.h b/src/__support/RPC/rpc_util.h
index ff9569298a1e..7a9901af83e7 100644
--- a/src/__support/RPC/rpc_util.h
+++ b/src/__support/RPC/rpc_util.h
@@ -6,32 +6,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTILS_H
-#define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTILS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
+#define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
#include "src/__support/CPP/type_traits.h"
#include "src/__support/GPU/utils.h"
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h"
#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/threads/sleep.h"
#include "src/string/memory_utils/generic/byte_per_byte.h"
#include "src/string/memory_utils/inline_memcpy.h"
namespace LIBC_NAMESPACE {
namespace rpc {
-/// Suspend the thread briefly to assist the thread scheduler during busy loops.
-LIBC_INLINE void sleep_briefly() {
-#if defined(LIBC_TARGET_ARCH_IS_NVPTX) && __CUDA_ARCH__ >= 700
- __nvvm_nanosleep(64);
-#elif defined(LIBC_TARGET_ARCH_IS_AMDGPU)
- __builtin_amdgcn_s_sleep(2);
-#elif defined(LIBC_TARGET_ARCH_IS_X86)
- __builtin_ia32_pause();
-#else
- // Simply do nothing if sleeping isn't supported on this platform.
-#endif
-}
-
/// Conditional to indicate if this process is running on the GPU.
LIBC_INLINE constexpr bool is_process_gpu() {
#if defined(LIBC_TARGET_ARCH_IS_GPU)
@@ -81,4 +69,4 @@ LIBC_INLINE void rpc_memcpy(void *dst, const void *src, size_t count) {
} // namespace rpc
} // namespace LIBC_NAMESPACE
-#endif
+#endif // LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
diff --git a/src/__support/StringUtil/message_mapper.h b/src/__support/StringUtil/message_mapper.h
index c93a57c62567..dd91839fb920 100644
--- a/src/__support/StringUtil/message_mapper.h
+++ b/src/__support/StringUtil/message_mapper.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_MESSAGE_MAPPER_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_MESSAGE_MAPPER_H
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/optional.h"
@@ -100,4 +100,4 @@ constexpr MsgTable<N1 + N2> operator+(const MsgTable<N1> &t1,
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_MESSAGE_MAPPER_H
diff --git a/src/__support/StringUtil/platform_errors.h b/src/__support/StringUtil/platform_errors.h
index dfa841ce5d82..32e8414b3e3d 100644
--- a/src/__support/StringUtil/platform_errors.h
+++ b/src/__support/StringUtil/platform_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_ERROR_TABLE_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_ERROR_TABLE_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_ERRORS_H
#if defined(__linux__) || defined(__Fuchsia__)
#include "tables/linux_platform_errors.h"
@@ -15,4 +15,4 @@
#include "tables/minimal_platform_errors.h"
#endif
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_ERROR_TABLE_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_ERRORS_H
diff --git a/src/__support/StringUtil/platform_signals.h b/src/__support/StringUtil/platform_signals.h
index 0a1c3f6bef25..52da082649bf 100644
--- a/src/__support/StringUtil/platform_signals.h
+++ b/src/__support/StringUtil/platform_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_SIGNAL_TABLE_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_SIGNAL_TABLE_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_SIGNALS_H
#if defined(__linux__) || defined(__Fuchsia__)
#include "tables/linux_platform_signals.h"
@@ -15,4 +15,4 @@
#include "tables/minimal_platform_signals.h"
#endif
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_PLATFORM_SIGNAL_TABLE_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_PLATFORM_SIGNALS_H
diff --git a/src/__support/StringUtil/tables/linux_extension_errors.h b/src/__support/StringUtil/tables/linux_extension_errors.h
index 4964fa47efd5..f48968892e96 100644
--- a/src/__support/StringUtil/tables/linux_extension_errors.h
+++ b/src/__support/StringUtil/tables/linux_extension_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_ERRORS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_ERRORS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_ERRORS_H
#include "src/__support/StringUtil/message_mapper.h"
@@ -72,4 +72,4 @@ constexpr MsgTable<52> LINUX_ERRORS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_ERRORS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_ERRORS_H
diff --git a/src/__support/StringUtil/tables/linux_extension_signals.h b/src/__support/StringUtil/tables/linux_extension_signals.h
index 633d0e2ed538..3f9f0c66ff24 100644
--- a/src/__support/StringUtil/tables/linux_extension_signals.h
+++ b/src/__support/StringUtil/tables/linux_extension_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
#include "src/__support/StringUtil/message_mapper.h"
@@ -30,4 +30,4 @@ LIBC_INLINE_VAR constexpr const MsgTable<3> LINUX_SIGNALS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_SIGNALS_H
diff --git a/src/__support/StringUtil/tables/linux_platform_errors.h b/src/__support/StringUtil/tables/linux_platform_errors.h
index a9ae2e8100a1..a7bb545d3bf9 100644
--- a/src/__support/StringUtil/tables/linux_platform_errors.h
+++ b/src/__support/StringUtil/tables/linux_platform_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_ERRORS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_ERRORS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_ERRORS_H
#include "linux_extension_errors.h"
#include "posix_errors.h"
@@ -20,4 +20,4 @@ LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS =
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_ERRORS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_ERRORS_H
diff --git a/src/__support/StringUtil/tables/linux_platform_signals.h b/src/__support/StringUtil/tables/linux_platform_signals.h
index 1daaa9cc6285..f12d31f222b0 100644
--- a/src/__support/StringUtil/tables/linux_platform_signals.h
+++ b/src/__support/StringUtil/tables/linux_platform_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
#include "linux_extension_signals.h"
#include "posix_signals.h"
@@ -20,4 +20,4 @@ LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS =
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_SIGNALS_H
diff --git a/src/__support/StringUtil/tables/minimal_platform_errors.h b/src/__support/StringUtil/tables/minimal_platform_errors.h
index 1cfd9e2e944d..c5672c4d875f 100644
--- a/src/__support/StringUtil/tables/minimal_platform_errors.h
+++ b/src/__support/StringUtil/tables/minimal_platform_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
#include "stdc_errors.h"
@@ -17,4 +17,4 @@ LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS = STDC_ERRORS;
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H
diff --git a/src/__support/StringUtil/tables/minimal_platform_signals.h b/src/__support/StringUtil/tables/minimal_platform_signals.h
index 7fcf91bfee85..7fe0dccfc465 100644
--- a/src/__support/StringUtil/tables/minimal_platform_signals.h
+++ b/src/__support/StringUtil/tables/minimal_platform_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
#include "stdc_signals.h"
@@ -17,4 +17,4 @@ LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS = STDC_SIGNALS;
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_SIGNALS_H
diff --git a/src/__support/StringUtil/tables/posix_errors.h b/src/__support/StringUtil/tables/posix_errors.h
index 3ade7aaab4f0..3cb6de394ea3 100644
--- a/src/__support/StringUtil/tables/posix_errors.h
+++ b/src/__support/StringUtil/tables/posix_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_ERRORS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_ERRORS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_ERRORS_H
#include "src/__support/StringUtil/message_mapper.h"
@@ -96,4 +96,4 @@ LIBC_INLINE_VAR constexpr MsgTable<76> POSIX_ERRORS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_ERRORS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_ERRORS_H
diff --git a/src/__support/StringUtil/tables/posix_signals.h b/src/__support/StringUtil/tables/posix_signals.h
index 2fba2d963f4b..b9535cbeb6f6 100644
--- a/src/__support/StringUtil/tables/posix_signals.h
+++ b/src/__support/StringUtil/tables/posix_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNALS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNALS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_SIGNALS_H
#include "src/__support/CPP/array.h"
#include "src/__support/StringUtil/message_mapper.h"
@@ -43,4 +43,4 @@ LIBC_INLINE_VAR constexpr MsgTable<22> POSIX_SIGNALS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNALS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_SIGNALS_H
diff --git a/src/__support/StringUtil/tables/signal_table.h b/src/__support/StringUtil/tables/signal_table.h
index 5035c54770c5..d7ffbc63722e 100644
--- a/src/__support/StringUtil/tables/signal_table.h
+++ b/src/__support/StringUtil/tables/signal_table.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_SIGNAL_TABLE_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_SIGNAL_TABLE_H
#include "src/__support/StringUtil/message_mapper.h"
@@ -36,4 +36,4 @@ LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS = []() {
} // namespace LIBC_NAMESPACE::internal
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_SIGNAL_TABLE_H
diff --git a/src/__support/StringUtil/tables/stdc_errors.h b/src/__support/StringUtil/tables/stdc_errors.h
index f0fc78710b18..a9c152783455 100644
--- a/src/__support/StringUtil/tables/stdc_errors.h
+++ b/src/__support/StringUtil/tables/stdc_errors.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_STDC_ERRORS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_STDC_ERRORS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_ERRORS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_ERRORS_H
#include "src/__support/StringUtil/message_mapper.h"
@@ -24,4 +24,4 @@ LIBC_INLINE_VAR constexpr const MsgTable<4> STDC_ERRORS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_ERRORS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_ERRORS_H
diff --git a/src/__support/StringUtil/tables/stdc_signals.h b/src/__support/StringUtil/tables/stdc_signals.h
index 773f182140ef..7c93b45a441c 100644
--- a/src/__support/StringUtil/tables/stdc_signals.h
+++ b/src/__support/StringUtil/tables/stdc_signals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_STDC_SIGNALS_H
-#define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_STDC_SIGNALS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_SIGNALS_H
+#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_SIGNALS_H
#include <signal.h> // For signal numbers
@@ -26,4 +26,4 @@ LIBC_INLINE_VAR constexpr const MsgTable<6> STDC_SIGNALS = {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_TABLES_LINUX_SIGNALS_H
+#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_SIGNALS_H
diff --git a/src/__support/UInt.h b/src/__support/UInt.h
index 7726b6d88f0d..c1e55ceef211 100644
--- a/src/__support/UInt.h
+++ b/src/__support/UInt.h
@@ -14,316 +14,524 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/type_traits.h"
-#include "src/__support/integer_utils.h"
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/math_extras.h" // SumCarry, DiffBorrow
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128, LIBC_TYPES_HAS_INT64
+#include "src/__support/math_extras.h" // add_with_carry, sub_with_borrow
#include "src/__support/number_pair.h"
#include <stddef.h> // For size_t
#include <stdint.h>
-namespace LIBC_NAMESPACE::cpp {
+namespace LIBC_NAMESPACE {
+
+namespace multiword {
+
+// A type trait mapping unsigned integers to their half-width unsigned
+// counterparts.
+template <typename T> struct half_width;
+template <> struct half_width<uint16_t> : cpp::type_identity<uint8_t> {};
+template <> struct half_width<uint32_t> : cpp::type_identity<uint16_t> {};
+#ifdef LIBC_TYPES_HAS_INT64
+template <> struct half_width<uint64_t> : cpp::type_identity<uint32_t> {};
+#ifdef LIBC_TYPES_HAS_INT128
+template <> struct half_width<__uint128_t> : cpp::type_identity<uint64_t> {};
+#endif // LIBC_TYPES_HAS_INT128
+#endif // LIBC_TYPES_HAS_INT64
+template <typename T> using half_width_t = typename half_width<T>::type;
+
+// An array of two elements that can be used in multiword operations.
+template <typename T> struct DoubleWide final : cpp::array<T, 2> {
+ using UP = cpp::array<T, 2>;
+ using UP::UP;
+ LIBC_INLINE constexpr DoubleWide(T lo, T hi) : UP({lo, hi}) {}
+};
+
+// Converts an unsigned value into a DoubleWide<half_width_t<T>>.
+template <typename T> LIBC_INLINE constexpr auto split(T value) {
+ static_assert(cpp::is_unsigned_v<T>);
+ using half_type = half_width_t<T>;
+ return DoubleWide<half_type>(
+ half_type(value),
+ half_type(value >> cpp::numeric_limits<half_type>::digits));
+}
+
+// The low part of a DoubleWide value.
+template <typename T> LIBC_INLINE constexpr T lo(const DoubleWide<T> &value) {
+ return value[0];
+}
+// The high part of a DoubleWide value.
+template <typename T> LIBC_INLINE constexpr T hi(const DoubleWide<T> &value) {
+ return value[1];
+}
+// The low part of an unsigned value.
+template <typename T> LIBC_INLINE constexpr half_width_t<T> lo(T value) {
+ return lo(split(value));
+}
+// The high part of an unsigned value.
+template <typename T> LIBC_INLINE constexpr half_width_t<T> hi(T value) {
+ return hi(split(value));
+}
+
+// Returns 'a' times 'b' in a DoubleWide<word>. Cannot overflow by construction.
+template <typename word>
+LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) {
+ if constexpr (cpp::is_same_v<word, uint8_t>) {
+ return split<uint16_t>(uint16_t(a) * uint16_t(b));
+ } else if constexpr (cpp::is_same_v<word, uint16_t>) {
+ return split<uint32_t>(uint32_t(a) * uint32_t(b));
+ }
+#ifdef LIBC_TYPES_HAS_INT64
+ else if constexpr (cpp::is_same_v<word, uint32_t>) {
+ return split<uint64_t>(uint64_t(a) * uint64_t(b));
+ }
+#endif
+#ifdef LIBC_TYPES_HAS_INT128
+ else if constexpr (cpp::is_same_v<word, uint64_t>) {
+ return split<__uint128_t>(__uint128_t(a) * __uint128_t(b));
+ }
+#endif
+ else {
+ using half_word = half_width_t<word>;
+ const auto shiftl = [](word value) -> word {
+ return value << cpp::numeric_limits<half_word>::digits;
+ };
+ const auto shiftr = [](word value) -> word {
+ return value >> cpp::numeric_limits<half_word>::digits;
+ };
+ // Here we do a one digit multiplication where 'a' and 'b' are of type
+ // word. We split 'a' and 'b' into half words and perform the classic long
+ // multiplication with 'a' and 'b' being two-digit numbers.
+
+ // a a_hi a_lo
+ // x b => x b_hi b_lo
+ // ---- -----------
+ // c result
+ // We convert 'lo' and 'hi' from 'half_word' to 'word' so multiplication
+ // doesn't overflow.
+ const word a_lo = lo(a);
+ const word b_lo = lo(b);
+ const word a_hi = hi(a);
+ const word b_hi = hi(b);
+ const word step1 = b_lo * a_lo; // no overflow;
+ const word step2 = b_lo * a_hi; // no overflow;
+ const word step3 = b_hi * a_lo; // no overflow;
+ const word step4 = b_hi * a_hi; // no overflow;
+ word lo_digit = step1;
+ word hi_digit = step4;
+ const word no_carry = 0;
+ word carry;
+ word _; // unused carry variable.
+ lo_digit = add_with_carry<word>(lo_digit, shiftl(step2), no_carry, carry);
+ hi_digit = add_with_carry<word>(hi_digit, shiftr(step2), carry, _);
+ lo_digit = add_with_carry<word>(lo_digit, shiftl(step3), no_carry, carry);
+ hi_digit = add_with_carry<word>(hi_digit, shiftr(step3), carry, _);
+ return DoubleWide<word>(lo_digit, hi_digit);
+ }
+}
-template <size_t Bits, bool Signed> struct BigInt {
+// In-place 'dst op= rhs' with operation with carry propagation. Returns carry.
+template <typename Function, typename word, size_t N, size_t M>
+LIBC_INLINE constexpr word inplace_binop(Function op_with_carry,
+ cpp::array<word, N> &dst,
+ const cpp::array<word, M> &rhs) {
+ static_assert(N >= M);
+ word carry_out = 0;
+ for (size_t i = 0; i < N; ++i) {
+ const bool has_rhs_value = i < M;
+ const word rhs_value = has_rhs_value ? rhs[i] : 0;
+ const word carry_in = carry_out;
+ dst[i] = op_with_carry(dst[i], rhs_value, carry_in, carry_out);
+ // stop early when rhs is over and no carry is to be propagated.
+ if (!has_rhs_value && carry_out == 0)
+ break;
+ }
+ return carry_out;
+}
- // This being hardcoded as 64 is okay because we're using uint64_t as our
- // internal type which will always be 64 bits.
- using word_type = uint64_t;
- LIBC_INLINE_VAR static constexpr size_t WORD_SIZE =
- sizeof(word_type) * CHAR_BIT;
+// In-place addition. Returns carry.
+template <typename word, size_t N, size_t M>
+LIBC_INLINE constexpr word add_with_carry(cpp::array<word, N> &dst,
+ const cpp::array<word, M> &rhs) {
+ return inplace_binop(LIBC_NAMESPACE::add_with_carry<word>, dst, rhs);
+}
- // TODO: Replace references to 64 with WORD_SIZE, and uint64_t with word_type.
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in BigInt should be a multiple of 64.");
- LIBC_INLINE_VAR static constexpr size_t WORDCOUNT = Bits / 64;
- cpp::array<word_type, WORDCOUNT> val{};
+// In-place subtraction. Returns borrow.
+template <typename word, size_t N, size_t M>
+LIBC_INLINE constexpr word sub_with_borrow(cpp::array<word, N> &dst,
+ const cpp::array<word, M> &rhs) {
+ return inplace_binop(LIBC_NAMESPACE::sub_with_borrow<word>, dst, rhs);
+}
+
+// In-place multiply-add. Returns carry.
+// i.e., 'dst += b * c'
+template <typename word, size_t N>
+LIBC_INLINE constexpr word mul_add_with_carry(cpp::array<word, N> &dst, word b,
+ word c) {
+ return add_with_carry(dst, mul2(b, c));
+}
+
+// An array of two elements serving as an accumulator during multiword
+// computations.
+template <typename T> struct Accumulator final : cpp::array<T, 2> {
+ using UP = cpp::array<T, 2>;
+ LIBC_INLINE constexpr Accumulator() : UP({0, 0}) {}
+ LIBC_INLINE constexpr T advance(T carry_in) {
+ auto result = UP::front();
+ UP::front() = UP::back();
+ UP::back() = carry_in;
+ return result;
+ }
+ LIBC_INLINE constexpr T sum() const { return UP::front(); }
+ LIBC_INLINE constexpr T carry() const { return UP::back(); }
+};
+
+// In-place multiplication by a single word. Returns carry.
+template <typename word, size_t N>
+LIBC_INLINE constexpr word scalar_multiply_with_carry(cpp::array<word, N> &dst,
+ word x) {
+ Accumulator<word> acc;
+ for (auto &val : dst) {
+ const word carry = mul_add_with_carry(acc, val, x);
+ val = acc.advance(carry);
+ }
+ return acc.carry();
+}
+
+// Multiplication of 'lhs' by 'rhs' into 'dst'. Returns carry.
+// This function is safe to use for signed numbers.
+// https://stackoverflow.com/a/20793834
+// https://pages.cs.wisc.edu/%7Emarkhill/cs354/Fall2008/beyond354/int.mult.html
+template <typename word, size_t O, size_t M, size_t N>
+LIBC_INLINE constexpr word multiply_with_carry(cpp::array<word, O> &dst,
+ const cpp::array<word, M> &lhs,
+ const cpp::array<word, N> &rhs) {
+ static_assert(O >= M + N);
+ Accumulator<word> acc;
+ for (size_t i = 0; i < O; ++i) {
+ const size_t lower_idx = i < N ? 0 : i - N + 1;
+ const size_t upper_idx = i < M ? i : M - 1;
+ word carry = 0;
+ for (size_t j = lower_idx; j <= upper_idx; ++j)
+ carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]);
+ dst[i] = acc.advance(carry);
+ }
+ return acc.carry();
+}
+
+template <typename word, size_t N>
+LIBC_INLINE constexpr void quick_mul_hi(cpp::array<word, N> &dst,
+ const cpp::array<word, N> &lhs,
+ const cpp::array<word, N> &rhs) {
+ Accumulator<word> acc;
+ word carry = 0;
+ // First round of accumulation for those at N - 1 in the full product.
+ for (size_t i = 0; i < N; ++i)
+ carry += mul_add_with_carry(acc, lhs[i], rhs[N - 1 - i]);
+ for (size_t i = N; i < 2 * N - 1; ++i) {
+ acc.advance(carry);
+ carry = 0;
+ for (size_t j = i - N + 1; j < N; ++j)
+ carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]);
+ dst[i - N] = acc.sum();
+ }
+ dst.back() = acc.carry();
+}
+
+template <typename word, size_t N>
+LIBC_INLINE constexpr bool is_negative(cpp::array<word, N> &array) {
+ using signed_word = cpp::make_signed_t<word>;
+ return cpp::bit_cast<signed_word>(array.back()) < 0;
+}
- LIBC_INLINE_VAR static constexpr uint64_t MASK32 = 0xFFFFFFFFu;
+// An enum for the shift function below.
+enum Direction { LEFT, RIGHT };
+
+// A bitwise shift on an array of elements.
+// TODO: Make the result UB when 'offset' is greater or equal to the number of
+// bits in 'array'. This will allow for better code performance.
+template <Direction direction, bool is_signed, typename word, size_t N>
+LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array,
+ size_t offset) {
+ static_assert(direction == LEFT || direction == RIGHT);
+ constexpr size_t WORD_BITS = cpp::numeric_limits<word>::digits;
+ constexpr size_t TOTAL_BITS = N * WORD_BITS;
+ if (LIBC_UNLIKELY(offset == 0))
+ return array;
+ if (LIBC_UNLIKELY(offset >= TOTAL_BITS))
+ return {};
+#ifdef LIBC_TYPES_HAS_INT128
+ if constexpr (TOTAL_BITS == 128) {
+ using type = cpp::conditional_t<is_signed, __int128_t, __uint128_t>;
+ auto tmp = cpp::bit_cast<type>(array);
+ if constexpr (direction == LEFT)
+ tmp <<= offset;
+ else
+ tmp >>= offset;
+ return cpp::bit_cast<cpp::array<word, N>>(tmp);
+ }
+#endif
+ const bool is_neg = is_signed && is_negative(array);
+ constexpr auto at = [](size_t index) -> int {
+ // reverse iteration when direction == LEFT.
+ if constexpr (direction == LEFT)
+ return int(N) - int(index) - 1;
+ return int(index);
+ };
+ const auto safe_get_at = [&](size_t index) -> word {
+ // return appropriate value when accessing out of bound elements.
+ const int i = at(index);
+ if (i < 0)
+ return 0;
+ if (i >= int(N))
+ return is_neg ? -1 : 0;
+ return array[i];
+ };
+ const size_t index_offset = offset / WORD_BITS;
+ const size_t bit_offset = offset % WORD_BITS;
+#ifdef LIBC_COMPILER_IS_CLANG
+ __builtin_assume(index_offset < N);
+#endif
+ cpp::array<word, N> out = {};
+ for (size_t index = 0; index < N; ++index) {
+ const word part1 = safe_get_at(index + index_offset);
+ const word part2 = safe_get_at(index + index_offset + 1);
+ word &dst = out[at(index)];
+ if (bit_offset == 0)
+ dst = part1; // no crosstalk between parts.
+ else if constexpr (direction == LEFT)
+ dst = (part1 << bit_offset) | (part2 >> (WORD_BITS - bit_offset));
+ else
+ dst = (part1 >> bit_offset) | (part2 << (WORD_BITS - bit_offset));
+ }
+ return out;
+}
- LIBC_INLINE static constexpr uint64_t low(uint64_t v) { return v & MASK32; }
- LIBC_INLINE static constexpr uint64_t high(uint64_t v) {
- return (v >> 32) & MASK32;
+#define DECLARE_COUNTBIT(NAME, INDEX_EXPR) \
+ template <typename word, size_t N> \
+ LIBC_INLINE constexpr int NAME(const cpp::array<word, N> &val) { \
+ int bit_count = 0; \
+ for (size_t i = 0; i < N; ++i) { \
+ const int word_count = cpp::NAME<word>(val[INDEX_EXPR]); \
+ bit_count += word_count; \
+ if (word_count != cpp::numeric_limits<word>::digits) \
+ break; \
+ } \
+ return bit_count; \
}
+DECLARE_COUNTBIT(countr_zero, i) // iterating forward
+DECLARE_COUNTBIT(countr_one, i) // iterating forward
+DECLARE_COUNTBIT(countl_zero, N - i - 1) // iterating backward
+DECLARE_COUNTBIT(countl_one, N - i - 1) // iterating backward
+
+} // namespace multiword
+
+template <size_t Bits, bool Signed, typename WordType = uint64_t>
+struct BigInt {
+private:
+ static_assert(cpp::is_integral_v<WordType> && cpp::is_unsigned_v<WordType>,
+ "WordType must be unsigned integer.");
+
+ struct Division {
+ BigInt quotient;
+ BigInt remainder;
+ };
+
+public:
+ using word_type = WordType;
+ using unsigned_type = BigInt<Bits, false, word_type>;
+ using signed_type = BigInt<Bits, true, word_type>;
+
+ LIBC_INLINE_VAR static constexpr bool SIGNED = Signed;
+ LIBC_INLINE_VAR static constexpr size_t BITS = Bits;
+ LIBC_INLINE_VAR
+ static constexpr size_t WORD_SIZE = sizeof(WordType) * CHAR_BIT;
+
+ static_assert(Bits > 0 && Bits % WORD_SIZE == 0,
+ "Number of bits in BigInt should be a multiple of WORD_SIZE.");
+
+ LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
+
+ cpp::array<WordType, WORD_COUNT> val{}; // zero initialized.
+
LIBC_INLINE constexpr BigInt() = default;
- LIBC_INLINE constexpr BigInt(const BigInt<Bits, Signed> &other) = default;
+ LIBC_INLINE constexpr BigInt(const BigInt &other) = default;
template <size_t OtherBits, bool OtherSigned>
- LIBC_INLINE constexpr BigInt(const BigInt<OtherBits, OtherSigned> &other) {
- if (OtherBits >= Bits) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
+ LIBC_INLINE constexpr BigInt(
+ const BigInt<OtherBits, OtherSigned, WordType> &other) {
+ if (OtherBits >= Bits) { // truncate
+ for (size_t i = 0; i < WORD_COUNT; ++i)
val[i] = other[i];
- } else {
+ } else { // zero or sign extend
size_t i = 0;
- for (; i < OtherBits / 64; ++i)
+ for (; i < OtherBits / WORD_SIZE; ++i)
val[i] = other[i];
- uint64_t sign = 0;
- if constexpr (Signed && OtherSigned) {
- sign = static_cast<uint64_t>(
- -static_cast<int64_t>(other[OtherBits / 64 - 1] >> 63));
- }
- for (; i < WORDCOUNT; ++i)
- val[i] = sign;
+ extend(i, Signed && other.is_neg());
}
}
// Construct a BigInt from a C array.
- template <size_t N, enable_if_t<N <= WORDCOUNT, int> = 0>
- LIBC_INLINE constexpr BigInt(const uint64_t (&nums)[N]) {
- size_t min_wordcount = N < WORDCOUNT ? N : WORDCOUNT;
- size_t i = 0;
- for (; i < min_wordcount; ++i)
+ template <size_t N> LIBC_INLINE constexpr BigInt(const WordType (&nums)[N]) {
+ static_assert(N == WORD_COUNT);
+ for (size_t i = 0; i < WORD_COUNT; ++i)
val[i] = nums[i];
+ }
- // If nums doesn't completely fill val, then fill the rest with zeroes.
- for (; i < WORDCOUNT; ++i)
- val[i] = 0;
+ LIBC_INLINE constexpr explicit BigInt(
+ const cpp::array<WordType, WORD_COUNT> &words) {
+ val = words;
}
// Initialize the first word to |v| and the rest to 0.
- template <typename T,
- typename = cpp::enable_if_t<is_integral_v<T> && sizeof(T) <= 16>>
+ template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T>>>
LIBC_INLINE constexpr BigInt(T v) {
- val[0] = static_cast<uint64_t>(v);
-
- if constexpr (Bits == 64)
- return;
-
- // Bits is at least 128.
- size_t i = 1;
- if constexpr (sizeof(T) == 16) {
- val[1] = static_cast<uint64_t>(v >> 64);
- i = 2;
- }
-
- uint64_t sign = (Signed && (v < 0)) ? 0xffff'ffff'ffff'ffff : 0;
- for (; i < WORDCOUNT; ++i) {
- val[i] = sign;
+ constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
+ const bool is_neg = Signed && (v < 0);
+ for (size_t i = 0; i < WORD_COUNT; ++i) {
+ if (v == 0) {
+ extend(i, is_neg);
+ return;
+ }
+ val[i] = static_cast<WordType>(v);
+ if constexpr (T_SIZE > WORD_SIZE)
+ v >>= WORD_SIZE;
+ else
+ v = 0;
}
}
-
- LIBC_INLINE constexpr explicit BigInt(
- const cpp::array<uint64_t, WORDCOUNT> &words) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- val[i] = words[i];
+ LIBC_INLINE constexpr BigInt &operator=(const BigInt &other) = default;
+
+ // constants
+ LIBC_INLINE static constexpr BigInt zero() { return BigInt(); }
+ LIBC_INLINE static constexpr BigInt one() { return BigInt(1); }
+ LIBC_INLINE static constexpr BigInt all_ones() { return ~zero(); }
+ LIBC_INLINE static constexpr BigInt min() {
+ BigInt out;
+ if constexpr (SIGNED)
+ out.set_msb();
+ return out;
+ }
+ LIBC_INLINE static constexpr BigInt max() {
+ BigInt out = all_ones();
+ if constexpr (SIGNED)
+ out.clear_msb();
+ return out;
}
+ // TODO: Reuse the Sign type.
+ LIBC_INLINE constexpr bool is_neg() const { return SIGNED && get_msb(); }
+
template <typename T> LIBC_INLINE constexpr explicit operator T() const {
return to<T>();
}
template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<
- cpp::is_integral_v<T> && sizeof(T) <= 8 && !cpp::is_same_v<T, bool>, T>
- to() const {
- return static_cast<T>(val[0]);
- }
- template <typename T>
- LIBC_INLINE constexpr cpp::enable_if_t<
- cpp::is_integral_v<T> && sizeof(T) == 16, T>
+ cpp::is_integral_v<T> && !cpp::is_same_v<T, bool>, T>
to() const {
- // T is 128-bit.
+ constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
T lo = static_cast<T>(val[0]);
-
- if constexpr (Bits == 64) {
- if constexpr (Signed) {
- // Extend sign for negative numbers.
- return (val[0] >> 63) ? ((T(-1) << 64) + lo) : lo;
- } else {
- return lo;
- }
- } else {
- return static_cast<T>((static_cast<T>(val[1]) << 64) + lo);
+ if constexpr (T_SIZE <= WORD_SIZE)
+ return lo;
+ constexpr size_t MAX_COUNT =
+ T_SIZE > Bits ? WORD_COUNT : T_SIZE / WORD_SIZE;
+ for (size_t i = 1; i < MAX_COUNT; ++i)
+ lo += static_cast<T>(val[i]) << (WORD_SIZE * i);
+ if constexpr (Signed && (T_SIZE > Bits)) {
+ // Extend sign for negative numbers.
+ constexpr T MASK = (~T(0) << Bits);
+ if (is_neg())
+ lo |= MASK;
}
+ return lo;
}
LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); }
- LIBC_INLINE BigInt<Bits, Signed> &
- operator=(const BigInt<Bits, Signed> &other) = default;
-
LIBC_INLINE constexpr bool is_zero() const {
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- if (val[i] != 0)
+ for (auto part : val)
+ if (part != 0)
return false;
- }
return true;
}
- // Add x to this number and store the result in this number.
+ // Add 'rhs' to this number and store the result in this number.
// Returns the carry value produced by the addition operation.
- LIBC_INLINE constexpr uint64_t add(const BigInt<Bits, Signed> &x) {
- SumCarry<uint64_t> s{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- s = add_with_carry_const(val[i], x.val[i], s.carry);
- val[i] = s.sum;
- }
- return s.carry;
+ LIBC_INLINE constexpr WordType add_overflow(const BigInt &rhs) {
+ return multiword::add_with_carry(val, rhs.val);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator+(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result;
- SumCarry<uint64_t> s{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- s = add_with_carry(val[i], other.val[i], s.carry);
- result.val[i] = s.sum;
- }
+ LIBC_INLINE constexpr BigInt operator+(const BigInt &other) const {
+ BigInt result = *this;
+ result.add_overflow(other);
return result;
}
// This will only apply when initializing a variable from constant values, so
// it will always use the constexpr version of add_with_carry.
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator+(BigInt<Bits, Signed> &&other) const {
- BigInt<Bits, Signed> result;
- SumCarry<uint64_t> s{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- s = add_with_carry_const(val[i], other.val[i], s.carry);
- result.val[i] = s.sum;
- }
- return result;
+ LIBC_INLINE constexpr BigInt operator+(BigInt &&other) const {
+ // We use addition commutativity to reuse 'other' and prevent allocation.
+ other.add_overflow(*this); // Returned carry value is ignored.
+ return other;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator+=(const BigInt<Bits, Signed> &other) {
- add(other); // Returned carry value is ignored.
+ LIBC_INLINE constexpr BigInt &operator+=(const BigInt &other) {
+ add_overflow(other); // Returned carry value is ignored.
return *this;
}
- // Subtract x to this number and store the result in this number.
+ // Subtract 'rhs' to this number and store the result in this number.
// Returns the carry value produced by the subtraction operation.
- LIBC_INLINE constexpr uint64_t sub(const BigInt<Bits, Signed> &x) {
- DiffBorrow<uint64_t> d{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- d = sub_with_borrow_const(val[i], x.val[i], d.borrow);
- val[i] = d.diff;
- }
- return d.borrow;
+ LIBC_INLINE constexpr WordType sub_overflow(const BigInt &rhs) {
+ return multiword::sub_with_borrow(val, rhs.val);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator-(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result;
- DiffBorrow<uint64_t> d{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- d = sub_with_borrow(val[i], other.val[i], d.borrow);
- result.val[i] = d.diff;
- }
+ LIBC_INLINE constexpr BigInt operator-(const BigInt &other) const {
+ BigInt result = *this;
+ result.sub_overflow(other); // Returned carry value is ignored.
return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator-(BigInt<Bits, Signed> &&other) const {
- BigInt<Bits, Signed> result;
- DiffBorrow<uint64_t> d{0, 0};
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- d = sub_with_borrow_const(val[i], other.val[i], d.borrow);
- result.val[i] = d.diff;
- }
+ LIBC_INLINE constexpr BigInt operator-(BigInt &&other) const {
+ BigInt result = *this;
+ result.sub_overflow(other); // Returned carry value is ignored.
return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator-=(const BigInt<Bits, Signed> &other) {
+ LIBC_INLINE constexpr BigInt &operator-=(const BigInt &other) {
// TODO(lntue): Set overflow flag / errno when carry is true.
- sub(other);
+ sub_overflow(other); // Returned carry value is ignored.
return *this;
}
- // Multiply this number with x and store the result in this number. It is
- // implemented using the long multiplication algorithm by splitting the
- // 64-bit words of this number and |x| in to 32-bit halves but peforming
- // the operations using 64-bit numbers. This ensures that we don't lose the
- // carry bits.
- // Returns the carry value produced by the multiplication operation.
- LIBC_INLINE constexpr uint64_t mul(uint64_t x) {
- BigInt<128, Signed> partial_sum(0);
- uint64_t carry = 0;
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- NumberPair<uint64_t> prod = full_mul(val[i], x);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
- carry += partial_sum.add(tmp);
- val[i] = partial_sum.val[0];
- partial_sum.val[0] = partial_sum.val[1];
- partial_sum.val[1] = carry;
- carry = 0;
- }
- return partial_sum.val[1];
+ // Multiply this number with x and store the result in this number.
+ LIBC_INLINE constexpr WordType mul(WordType x) {
+ return multiword::scalar_multiply_with_carry(val, x);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator*(const BigInt<Bits, Signed> &other) const {
- if constexpr (Signed) {
- BigInt<Bits, false> a(*this);
- BigInt<Bits, false> b(other);
- bool a_neg = (a.val[WORDCOUNT - 1] >> 63);
- bool b_neg = (b.val[WORDCOUNT - 1] >> 63);
- if (a_neg)
- a = -a;
- if (b_neg)
- b = -b;
- BigInt<Bits, false> prod = a * b;
- if (a_neg != b_neg)
- prod = -prod;
- return static_cast<BigInt<Bits, true>>(prod);
- } else {
-
- if constexpr (WORDCOUNT == 1) {
- return {val[0] * other.val[0]};
- } else {
- BigInt<Bits, Signed> result(0);
- BigInt<128, Signed> partial_sum(0);
- uint64_t carry = 0;
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- for (size_t j = 0; j <= i; j++) {
- NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
- carry += partial_sum.add(tmp);
- }
- result.val[i] = partial_sum.val[0];
- partial_sum.val[0] = partial_sum.val[1];
- partial_sum.val[1] = carry;
- carry = 0;
- }
- return result;
- }
- }
- }
-
- // Return the full product, only unsigned for now.
+ // Return the full product.
template <size_t OtherBits>
- LIBC_INLINE constexpr BigInt<Bits + OtherBits, Signed>
- ful_mul(const BigInt<OtherBits, Signed> &other) const {
- BigInt<Bits + OtherBits, Signed> result(0);
- BigInt<128, Signed> partial_sum(0);
- uint64_t carry = 0;
- constexpr size_t OTHER_WORDCOUNT = BigInt<OtherBits, Signed>::WORDCOUNT;
- for (size_t i = 0; i <= WORDCOUNT + OTHER_WORDCOUNT - 2; ++i) {
- const size_t lower_idx =
- i < OTHER_WORDCOUNT ? 0 : i - OTHER_WORDCOUNT + 1;
- const size_t upper_idx = i < WORDCOUNT ? i : WORDCOUNT - 1;
- for (size_t j = lower_idx; j <= upper_idx; ++j) {
- NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
- carry += partial_sum.add(tmp);
- }
- result.val[i] = partial_sum.val[0];
- partial_sum.val[0] = partial_sum.val[1];
- partial_sum.val[1] = carry;
- carry = 0;
- }
- result.val[WORDCOUNT + OTHER_WORDCOUNT - 1] = partial_sum.val[0];
+ LIBC_INLINE constexpr auto
+ ful_mul(const BigInt<OtherBits, Signed, WordType> &other) const {
+ BigInt<Bits + OtherBits, Signed, WordType> result;
+ multiword::multiply_with_carry(result.val, val, other.val);
return result;
}
+ LIBC_INLINE constexpr BigInt operator*(const BigInt &other) const {
+ // Perform full mul and truncate.
+ return BigInt(ful_mul(other));
+ }
+
// Fast hi part of the full product. The normal product `operator*` returns
// `Bits` least significant bits of the full product, while this function will
// approximate `Bits` most significant bits of the full product with errors
// bounded by:
- // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORDCOUNT - 1.
+ // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORD_COUNT - 1.
//
// An example usage of this is to quickly (but less accurately) compute the
// product of (normalized) mantissas of floating point numbers:
@@ -335,92 +543,53 @@ template <size_t Bits, bool Signed> struct BigInt {
//
// Performance summary:
// Number of 64-bit x 64-bit -> 128-bit multiplications performed.
- // Bits WORDCOUNT ful_mul quick_mul_hi Error bound
+ // Bits WORD_COUNT ful_mul quick_mul_hi Error bound
// 128 2 4 3 1
// 196 3 9 6 2
// 256 4 16 10 3
// 512 8 64 36 7
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- quick_mul_hi(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result(0);
- BigInt<128, Signed> partial_sum(0);
- uint64_t carry = 0;
- // First round of accumulation for those at WORDCOUNT - 1 in the full
- // product.
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- NumberPair<uint64_t> prod =
- full_mul(val[i], other.val[WORDCOUNT - 1 - i]);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
- carry += partial_sum.add(tmp);
- }
- for (size_t i = WORDCOUNT; i < 2 * WORDCOUNT - 1; ++i) {
- partial_sum.val[0] = partial_sum.val[1];
- partial_sum.val[1] = carry;
- carry = 0;
- for (size_t j = i - WORDCOUNT + 1; j < WORDCOUNT; ++j) {
- NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
- carry += partial_sum.add(tmp);
- }
- result.val[i - WORDCOUNT] = partial_sum.val[0];
- }
- result.val[WORDCOUNT - 1] = partial_sum.val[1];
+ LIBC_INLINE constexpr BigInt quick_mul_hi(const BigInt &other) const {
+ BigInt result;
+ multiword::quick_mul_hi(result.val, val, other.val);
return result;
}
- // pow takes a power and sets this to its starting value to that power. Zero
- // to the zeroth power returns 1.
+ // BigInt(x).pow_n(n) computes x ^ n.
+ // Note 0 ^ 0 == 1.
LIBC_INLINE constexpr void pow_n(uint64_t power) {
- BigInt<Bits, Signed> result = 1;
- BigInt<Bits, Signed> cur_power = *this;
-
+ static_assert(!Signed);
+ BigInt result = one();
+ BigInt cur_power = *this;
while (power > 0) {
- if ((power % 2) > 0) {
- result = result * cur_power;
- }
- power = power >> 1;
+ if ((power % 2) > 0)
+ result *= cur_power;
+ power >>= 1;
cur_power *= cur_power;
}
*this = result;
}
- // TODO: Make division work correctly for signed integers.
-
- // div takes another BigInt of the same size and divides this by it. The value
- // of this will be set to the quotient, and the return value is the remainder.
- LIBC_INLINE constexpr optional<BigInt<Bits, Signed>>
- div(const BigInt<Bits, Signed> &other) {
- BigInt<Bits, Signed> remainder(0);
- if (*this < other) {
- remainder = *this;
- *this = BigInt<Bits, Signed>(0);
- return remainder;
- }
- if (other == 1) {
- return remainder;
- }
- if (other == 0) {
- return nullopt;
- }
-
- BigInt<Bits, Signed> quotient(0);
- BigInt<Bits, Signed> subtractor = other;
- int cur_bit = static_cast<int>(subtractor.clz() - this->clz());
- subtractor.shift_left(cur_bit);
-
- for (; cur_bit >= 0 && *this > 0; --cur_bit, subtractor.shift_right(1)) {
- if (*this >= subtractor) {
- this->sub(subtractor);
- quotient = quotient | (BigInt<Bits, Signed>(1) << cur_bit);
- }
- }
- remainder = *this;
- *this = quotient;
- return remainder;
+ // Performs inplace signed / unsigned division. Returns remainder if not
+ // dividing by zero.
+ // For signed numbers it behaves like C++ signed integer division.
+ // That is by truncating the fractionnal part
+ // https://stackoverflow.com/a/3602857
+ LIBC_INLINE constexpr cpp::optional<BigInt> div(const BigInt &divider) {
+ if (LIBC_UNLIKELY(divider.is_zero()))
+ return cpp::nullopt;
+ if (LIBC_UNLIKELY(divider == BigInt::one()))
+ return BigInt::zero();
+ Division result;
+ if constexpr (SIGNED)
+ result = divide_signed(*this, divider);
+ else
+ result = divide_unsigned(*this, divider);
+ *this = result.quotient;
+ return result.remainder;
}
- // Efficiently perform BigInt / (x * 2^e), where x is a 32-bit unsigned
- // integer, and return the remainder. The main idea is as follow:
+ // Efficiently perform BigInt / (x * 2^e), where x is a half-word-size
+ // unsigned integer, and return the remainder. The main idea is as follow:
// Let q = y / (x * 2^e) be the quotient, and
// r = y % (x * 2^e) be the remainder.
// First, notice that:
@@ -428,102 +597,106 @@ template <size_t Bits, bool Signed> struct BigInt {
// so we just need to focus on all the bits of y that is >= 2^e.
// To speed up the shift-and-add steps, we only use x as the divisor, and
// performing 32-bit shiftings instead of bit-by-bit shiftings.
- // Since the remainder of each division step < x < 2^32, the computation of
- // each step is now properly contained within uint64_t.
+ // Since the remainder of each division step < x < 2^(WORD_SIZE / 2), the
+ // computation of each step is now properly contained within WordType.
// And finally we perform some extra alignment steps for the remaining bits.
- LIBC_INLINE constexpr optional<BigInt<Bits, Signed>>
- div_uint32_times_pow_2(uint32_t x, size_t e) {
- BigInt<Bits, Signed> remainder(0);
-
- if (x == 0) {
- return nullopt;
- }
+ LIBC_INLINE constexpr cpp::optional<BigInt>
+ div_uint_half_times_pow_2(multiword::half_width_t<WordType> x, size_t e) {
+ BigInt remainder;
+ if (x == 0)
+ return cpp::nullopt;
if (e >= Bits) {
remainder = *this;
- *this = BigInt<Bits, false>(0);
+ *this = BigInt<Bits, false, WordType>();
return remainder;
}
-
- BigInt<Bits, Signed> quotient(0);
- uint64_t x64 = static_cast<uint64_t>(x);
- // lower64 = smallest multiple of 64 that is >= e.
- size_t lower64 = ((e >> 6) + ((e & 63) != 0)) << 6;
- // lower_pos is the index of the closest 64-bit chunk >= 2^e.
- size_t lower_pos = lower64 / 64;
+ BigInt quotient;
+ WordType x_word = static_cast<WordType>(x);
+ constexpr size_t LOG2_WORD_SIZE = cpp::bit_width(WORD_SIZE) - 1;
+ constexpr size_t HALF_WORD_SIZE = WORD_SIZE >> 1;
+ constexpr WordType HALF_MASK = ((WordType(1) << HALF_WORD_SIZE) - 1);
+ // lower = smallest multiple of WORD_SIZE that is >= e.
+ size_t lower = ((e >> LOG2_WORD_SIZE) + ((e & (WORD_SIZE - 1)) != 0))
+ << LOG2_WORD_SIZE;
+ // lower_pos is the index of the closest WORD_SIZE-bit chunk >= 2^e.
+ size_t lower_pos = lower / WORD_SIZE;
// Keep track of current remainder mod x * 2^(32*i)
- uint64_t rem = 0;
+ WordType rem = 0;
// pos is the index of the current 64-bit chunk that we are processing.
- size_t pos = WORDCOUNT;
+ size_t pos = WORD_COUNT;
// TODO: look into if constexpr(Bits > 256) skip leading zeroes.
- for (size_t q_pos = WORDCOUNT - lower_pos; q_pos > 0; --q_pos) {
- // q_pos is 1 + the index of the current 64-bit chunk of the quotient
- // being processed.
- // Performing the division / modulus with divisor:
- // x * 2^(64*q_pos - 32),
- // i.e. using the upper 32-bit of the current 64-bit chunk.
- rem <<= 32;
- rem += val[--pos] >> 32;
- uint64_t q_tmp = rem / x64;
- rem %= x64;
+ for (size_t q_pos = WORD_COUNT - lower_pos; q_pos > 0; --q_pos) {
+ // q_pos is 1 + the index of the current WORD_SIZE-bit chunk of the
+ // quotient being processed. Performing the division / modulus with
+ // divisor:
+ // x * 2^(WORD_SIZE*q_pos - WORD_SIZE/2),
+ // i.e. using the upper (WORD_SIZE/2)-bit of the current WORD_SIZE-bit
+ // chunk.
+ rem <<= HALF_WORD_SIZE;
+ rem += val[--pos] >> HALF_WORD_SIZE;
+ WordType q_tmp = rem / x_word;
+ rem %= x_word;
// Performing the division / modulus with divisor:
- // x * 2^(64*(q_pos - 1)),
- // i.e. using the lower 32-bit of the current 64-bit chunk.
- rem <<= 32;
- rem += val[pos] & MASK32;
- quotient.val[q_pos - 1] = (q_tmp << 32) + rem / x64;
- rem %= x64;
+ // x * 2^(WORD_SIZE*(q_pos - 1)),
+ // i.e. using the lower (WORD_SIZE/2)-bit of the current WORD_SIZE-bit
+ // chunk.
+ rem <<= HALF_WORD_SIZE;
+ rem += val[pos] & HALF_MASK;
+ quotient.val[q_pos - 1] = (q_tmp << HALF_WORD_SIZE) + rem / x_word;
+ rem %= x_word;
}
// So far, what we have is:
- // quotient = y / (x * 2^lower64), and
- // rem = (y % (x * 2^lower64)) / 2^lower64.
- // If (lower64 > e), we will need to perform an extra adjustment of the
+ // quotient = y / (x * 2^lower), and
+ // rem = (y % (x * 2^lower)) / 2^lower.
+ // If (lower > e), we will need to perform an extra adjustment of the
// quotient and remainder, namely:
- // y / (x * 2^e) = [ y / (x * 2^lower64) ] * 2^(lower64 - e) +
- // + (rem * 2^(lower64 - e)) / x
- // (y % (x * 2^e)) / 2^e = (rem * 2^(lower64 - e)) % x
- size_t last_shift = lower64 - e;
+ // y / (x * 2^e) = [ y / (x * 2^lower) ] * 2^(lower - e) +
+ // + (rem * 2^(lower - e)) / x
+ // (y % (x * 2^e)) / 2^e = (rem * 2^(lower - e)) % x
+ size_t last_shift = lower - e;
if (last_shift > 0) {
- // quotient * 2^(lower64 - e)
+ // quotient * 2^(lower - e)
quotient <<= last_shift;
- uint64_t q_tmp = 0;
- uint64_t d = val[--pos];
- if (last_shift >= 32) {
- // The shifting (rem * 2^(lower64 - e)) might overflow uint64_t, so we
- // perform a 32-bit shift first.
- rem <<= 32;
- rem += d >> 32;
- d &= MASK32;
- q_tmp = rem / x64;
- rem %= x64;
- last_shift -= 32;
+ WordType q_tmp = 0;
+ WordType d = val[--pos];
+ if (last_shift >= HALF_WORD_SIZE) {
+ // The shifting (rem * 2^(lower - e)) might overflow WordTyoe, so we
+ // perform a HALF_WORD_SIZE-bit shift first.
+ rem <<= HALF_WORD_SIZE;
+ rem += d >> HALF_WORD_SIZE;
+ d &= HALF_MASK;
+ q_tmp = rem / x_word;
+ rem %= x_word;
+ last_shift -= HALF_WORD_SIZE;
} else {
- // Only use the upper 32-bit of the current 64-bit chunk.
- d >>= 32;
+ // Only use the upper HALF_WORD_SIZE-bit of the current WORD_SIZE-bit
+ // chunk.
+ d >>= HALF_WORD_SIZE;
}
if (last_shift > 0) {
- rem <<= 32;
+ rem <<= HALF_WORD_SIZE;
rem += d;
q_tmp <<= last_shift;
- x64 <<= 32 - last_shift;
- q_tmp += rem / x64;
- rem %= x64;
+ x_word <<= HALF_WORD_SIZE - last_shift;
+ q_tmp += rem / x_word;
+ rem %= x_word;
}
quotient.val[0] += q_tmp;
- if (lower64 - e <= 32) {
- // The remainder rem * 2^(lower64 - e) might overflow to the higher
- // 64-bit chunk.
- if (pos < WORDCOUNT - 1) {
- remainder[pos + 1] = rem >> 32;
+ if (lower - e <= HALF_WORD_SIZE) {
+ // The remainder rem * 2^(lower - e) might overflow to the higher
+ // WORD_SIZE-bit chunk.
+ if (pos < WORD_COUNT - 1) {
+ remainder[pos + 1] = rem >> HALF_WORD_SIZE;
}
- remainder[pos] = (rem << 32) + (val[pos] & MASK32);
+ remainder[pos] = (rem << HALF_WORD_SIZE) + (val[pos] & HALF_MASK);
} else {
remainder[pos] = rem;
}
@@ -541,470 +714,571 @@ template <size_t Bits, bool Signed> struct BigInt {
return remainder;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator/(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result(*this);
+ LIBC_INLINE constexpr BigInt operator/(const BigInt &other) const {
+ BigInt result(*this);
result.div(other);
return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator/=(const BigInt<Bits, Signed> &other) {
+ LIBC_INLINE constexpr BigInt &operator/=(const BigInt &other) {
div(other);
return *this;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator%(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result(*this);
+ LIBC_INLINE constexpr BigInt operator%(const BigInt &other) const {
+ BigInt result(*this);
return *result.div(other);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator*=(const BigInt<Bits, Signed> &other) {
+ LIBC_INLINE constexpr BigInt &operator*=(const BigInt &other) {
*this = *this * other;
return *this;
}
- LIBC_INLINE constexpr uint64_t clz() {
- uint64_t leading_zeroes = 0;
- for (size_t i = WORDCOUNT; i > 0; --i) {
- if (val[i - 1] == 0) {
- leading_zeroes += sizeof(uint64_t) * 8;
- } else {
- leading_zeroes += countl_zero(val[i - 1]);
- break;
- }
- }
- return leading_zeroes;
- }
-
- LIBC_INLINE constexpr void shift_left(size_t s) {
-#ifdef __SIZEOF_INT128__
- if constexpr (Bits == 128) {
- // Use builtin 128 bits if available;
- if (s >= 128) {
- val[0] = 0;
- val[1] = 0;
- return;
- }
- __uint128_t tmp = __uint128_t(val[0]) + (__uint128_t(val[1]) << 64);
- tmp <<= s;
- val[0] = uint64_t(tmp);
- val[1] = uint64_t(tmp >> 64);
- return;
- }
-#endif // __SIZEOF_INT128__
- if (LIBC_UNLIKELY(s == 0))
- return;
-
- const size_t drop = s / 64; // Number of words to drop
- const size_t shift = s % 64; // Bits to shift in the remaining words.
- size_t i = WORDCOUNT;
-
- if (drop < WORDCOUNT) {
- i = WORDCOUNT - 1;
- if (shift > 0) {
- for (size_t j = WORDCOUNT - 1 - drop; j > 0; --i, --j) {
- val[i] = (val[j] << shift) | (val[j - 1] >> (64 - shift));
- }
- val[i] = val[0] << shift;
- } else {
- for (size_t j = WORDCOUNT - 1 - drop; j > 0; --i, --j) {
- val[i] = val[j];
- }
- val[i] = val[0];
- }
- }
-
- for (size_t j = 0; j < i; ++j) {
- val[j] = 0;
- }
+ LIBC_INLINE constexpr BigInt &operator<<=(size_t s) {
+ val = multiword::shift<multiword::LEFT, SIGNED>(val, s);
+ return *this;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator<<(size_t s) const {
- BigInt<Bits, Signed> result(*this);
- result.shift_left(s);
- return result;
+ LIBC_INLINE constexpr BigInt operator<<(size_t s) const {
+ return BigInt(multiword::shift<multiword::LEFT, SIGNED>(val, s));
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &operator<<=(size_t s) {
- shift_left(s);
+ LIBC_INLINE constexpr BigInt &operator>>=(size_t s) {
+ val = multiword::shift<multiword::RIGHT, SIGNED>(val, s);
return *this;
}
- LIBC_INLINE constexpr void shift_right(size_t s) {
-#ifdef __SIZEOF_INT128__
- if constexpr (Bits == 128) {
- // Use builtin 128 bits if available;
- if (s >= 128) {
- val[0] = 0;
- val[1] = 0;
- return;
- }
- __uint128_t tmp = __uint128_t(val[0]) + (__uint128_t(val[1]) << 64);
- if constexpr (Signed) {
- tmp = static_cast<__uint128_t>(static_cast<__int128_t>(tmp) >> s);
- } else {
- tmp >>= s;
- }
- val[0] = uint64_t(tmp);
- val[1] = uint64_t(tmp >> 64);
- return;
- }
-#endif // __SIZEOF_INT128__
-
- if (LIBC_UNLIKELY(s == 0))
- return;
- const size_t drop = s / 64; // Number of words to drop
- const size_t shift = s % 64; // Bit shift in the remaining words.
+ LIBC_INLINE constexpr BigInt operator>>(size_t s) const {
+ return BigInt(multiword::shift<multiword::RIGHT, SIGNED>(val, s));
+ }
- size_t i = 0;
- uint64_t sign = Signed ? (val[WORDCOUNT - 1] >> 63) : 0;
+#define DEFINE_BINOP(OP) \
+ LIBC_INLINE friend constexpr BigInt operator OP(const BigInt &lhs, \
+ const BigInt &rhs) { \
+ BigInt result; \
+ for (size_t i = 0; i < WORD_COUNT; ++i) \
+ result[i] = lhs[i] OP rhs[i]; \
+ return result; \
+ } \
+ LIBC_INLINE friend constexpr BigInt operator OP##=(BigInt &lhs, \
+ const BigInt &rhs) { \
+ for (size_t i = 0; i < WORD_COUNT; ++i) \
+ lhs[i] OP## = rhs[i]; \
+ return lhs; \
+ }
- if (drop < WORDCOUNT) {
- if (shift > 0) {
- for (size_t j = drop; j < WORDCOUNT - 1; ++i, ++j) {
- val[i] = (val[j] >> shift) | (val[j + 1] << (64 - shift));
- }
- if constexpr (Signed) {
- val[i] = static_cast<uint64_t>(
- static_cast<int64_t>(val[WORDCOUNT - 1]) >> shift);
- } else {
- val[i] = val[WORDCOUNT - 1] >> shift;
- }
- ++i;
- } else {
- for (size_t j = drop; j < WORDCOUNT; ++i, ++j) {
- val[i] = val[j];
- }
- }
- }
+ DEFINE_BINOP(&) // & and &=
+ DEFINE_BINOP(|) // | and |=
+ DEFINE_BINOP(^) // ^ and ^=
+#undef DEFINE_BINOP
- for (; i < WORDCOUNT; ++i) {
- val[i] = sign;
- }
+ LIBC_INLINE constexpr BigInt operator~() const {
+ BigInt result;
+ for (size_t i = 0; i < WORD_COUNT; ++i)
+ result[i] = ~val[i];
+ return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator>>(size_t s) const {
- BigInt<Bits, Signed> result(*this);
- result.shift_right(s);
+ LIBC_INLINE constexpr BigInt operator-() const {
+ BigInt result(*this);
+ result.negate();
return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &operator>>=(size_t s) {
- shift_right(s);
- return *this;
+ LIBC_INLINE friend constexpr bool operator==(const BigInt &lhs,
+ const BigInt &rhs) {
+ for (size_t i = 0; i < WORD_COUNT; ++i)
+ if (lhs.val[i] != rhs.val[i])
+ return false;
+ return true;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator&(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result;
- for (size_t i = 0; i < WORDCOUNT; ++i)
- result.val[i] = val[i] & other.val[i];
- return result;
+ LIBC_INLINE friend constexpr bool operator!=(const BigInt &lhs,
+ const BigInt &rhs) {
+ return !(lhs == rhs);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator&=(const BigInt<Bits, Signed> &other) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- val[i] &= other.val[i];
- return *this;
+ LIBC_INLINE friend constexpr bool operator>(const BigInt &lhs,
+ const BigInt &rhs) {
+ return cmp(lhs, rhs) > 0;
}
-
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator|(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result;
- for (size_t i = 0; i < WORDCOUNT; ++i)
- result.val[i] = val[i] | other.val[i];
- return result;
+ LIBC_INLINE friend constexpr bool operator>=(const BigInt &lhs,
+ const BigInt &rhs) {
+ return cmp(lhs, rhs) >= 0;
+ }
+ LIBC_INLINE friend constexpr bool operator<(const BigInt &lhs,
+ const BigInt &rhs) {
+ return cmp(lhs, rhs) < 0;
+ }
+ LIBC_INLINE friend constexpr bool operator<=(const BigInt &lhs,
+ const BigInt &rhs) {
+ return cmp(lhs, rhs) <= 0;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator|=(const BigInt<Bits, Signed> &other) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- val[i] |= other.val[i];
+ LIBC_INLINE constexpr BigInt &operator++() {
+ increment();
return *this;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator^(const BigInt<Bits, Signed> &other) const {
- BigInt<Bits, Signed> result;
- for (size_t i = 0; i < WORDCOUNT; ++i)
- result.val[i] = val[i] ^ other.val[i];
- return result;
+ LIBC_INLINE constexpr BigInt operator++(int) {
+ BigInt oldval(*this);
+ increment();
+ return oldval;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &
- operator^=(const BigInt<Bits, Signed> &other) {
- for (size_t i = 0; i < WORDCOUNT; ++i)
- val[i] ^= other.val[i];
+ LIBC_INLINE constexpr BigInt &operator--() {
+ decrement();
return *this;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator~() const {
- BigInt<Bits, Signed> result;
- for (size_t i = 0; i < WORDCOUNT; ++i)
- result.val[i] = ~val[i];
- return result;
+ LIBC_INLINE constexpr BigInt operator--(int) {
+ BigInt oldval(*this);
+ decrement();
+ return oldval;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator-() const {
- BigInt<Bits, Signed> result = ~(*this);
- result.add(BigInt<Bits, Signed>(1));
- return result;
+ // Return the i-th word of the number.
+ LIBC_INLINE constexpr const WordType &operator[](size_t i) const {
+ return val[i];
}
- LIBC_INLINE constexpr bool
- operator==(const BigInt<Bits, Signed> &other) const {
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- if (val[i] != other.val[i])
- return false;
- }
- return true;
- }
+ // Return the i-th word of the number.
+ LIBC_INLINE constexpr WordType &operator[](size_t i) { return val[i]; }
- LIBC_INLINE constexpr bool
- operator!=(const BigInt<Bits, Signed> &other) const {
- for (size_t i = 0; i < WORDCOUNT; ++i) {
- if (val[i] != other.val[i])
- return true;
+private:
+ LIBC_INLINE friend constexpr int cmp(const BigInt &lhs, const BigInt &rhs) {
+ constexpr auto compare = [](WordType a, WordType b) {
+ return a == b ? 0 : a > b ? 1 : -1;
+ };
+ if constexpr (Signed) {
+ const bool lhs_is_neg = lhs.is_neg();
+ const bool rhs_is_neg = rhs.is_neg();
+ if (lhs_is_neg != rhs_is_neg)
+ return rhs_is_neg ? 1 : -1;
}
- return false;
+ for (size_t i = WORD_COUNT; i-- > 0;)
+ if (auto cmp = compare(lhs[i], rhs[i]); cmp != 0)
+ return cmp;
+ return 0;
}
- LIBC_INLINE constexpr bool
- operator>(const BigInt<Bits, Signed> &other) const {
- if constexpr (Signed) {
- // Check for different signs;
- bool a_sign = val[WORDCOUNT - 1] >> 63;
- bool b_sign = other.val[WORDCOUNT - 1] >> 63;
- if (a_sign != b_sign) {
- return b_sign;
- }
- }
- for (size_t i = WORDCOUNT; i > 0; --i) {
- uint64_t word = val[i - 1];
- uint64_t other_word = other.val[i - 1];
- if (word > other_word)
- return true;
- else if (word < other_word)
- return false;
- }
- // Equal
- return false;
+ LIBC_INLINE constexpr void bitwise_not() {
+ for (auto &part : val)
+ part = ~part;
}
- LIBC_INLINE constexpr bool
- operator>=(const BigInt<Bits, Signed> &other) const {
- if constexpr (Signed) {
- // Check for different signs;
- bool a_sign = val[WORDCOUNT - 1] >> 63;
- bool b_sign = other.val[WORDCOUNT - 1] >> 63;
- if (a_sign != b_sign) {
- return b_sign;
- }
- }
- for (size_t i = WORDCOUNT; i > 0; --i) {
- uint64_t word = val[i - 1];
- uint64_t other_word = other.val[i - 1];
- if (word > other_word)
- return true;
- else if (word < other_word)
- return false;
- }
- // Equal
- return true;
+ LIBC_INLINE constexpr void negate() {
+ bitwise_not();
+ increment();
}
- LIBC_INLINE constexpr bool
- operator<(const BigInt<Bits, Signed> &other) const {
- if constexpr (Signed) {
- // Check for different signs;
- bool a_sign = val[WORDCOUNT - 1] >> 63;
- bool b_sign = other.val[WORDCOUNT - 1] >> 63;
- if (a_sign != b_sign) {
- return a_sign;
- }
- }
+ LIBC_INLINE constexpr void increment() {
+ multiword::add_with_carry(val, cpp::array<WordType, 1>{1});
+ }
- for (size_t i = WORDCOUNT; i > 0; --i) {
- uint64_t word = val[i - 1];
- uint64_t other_word = other.val[i - 1];
- if (word > other_word)
- return false;
- else if (word < other_word)
- return true;
- }
- // Equal
- return false;
+ LIBC_INLINE constexpr void decrement() {
+ multiword::add_with_carry(val, cpp::array<WordType, 1>{1});
}
- LIBC_INLINE constexpr bool
- operator<=(const BigInt<Bits, Signed> &other) const {
- if constexpr (Signed) {
- // Check for different signs;
- bool a_sign = val[WORDCOUNT - 1] >> 63;
- bool b_sign = other.val[WORDCOUNT - 1] >> 63;
- if (a_sign != b_sign) {
- return a_sign;
- }
- }
- for (size_t i = WORDCOUNT; i > 0; --i) {
- uint64_t word = val[i - 1];
- uint64_t other_word = other.val[i - 1];
- if (word > other_word)
- return false;
- else if (word < other_word)
- return true;
- }
- // Equal
- return true;
+ LIBC_INLINE constexpr void extend(size_t index, bool is_neg) {
+ const WordType value = is_neg ? cpp::numeric_limits<WordType>::max()
+ : cpp::numeric_limits<WordType>::min();
+ for (size_t i = index; i < WORD_COUNT; ++i)
+ val[i] = value;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &operator++() {
- BigInt<Bits, Signed> one(1);
- add(one);
- return *this;
+ LIBC_INLINE constexpr bool get_msb() const {
+ return val.back() >> (WORD_SIZE - 1);
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator++(int) {
- BigInt<Bits, Signed> oldval(*this);
- BigInt<Bits, Signed> one(1);
- add(one);
- return oldval;
+ LIBC_INLINE constexpr void set_msb() {
+ val.back() |= mask_leading_ones<WordType, 1>();
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> &operator--() {
- BigInt<Bits, Signed> one(1);
- sub(one);
- return *this;
+ LIBC_INLINE constexpr void clear_msb() {
+ val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>();
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator--(int) {
- BigInt<Bits, Signed> oldval(*this);
- BigInt<Bits, Signed> one(1);
- sub(one);
- return oldval;
+ LIBC_INLINE constexpr void set_bit(size_t i) {
+ const size_t word_index = i / WORD_SIZE;
+ val[word_index] |= WordType(1) << (i % WORD_SIZE);
}
- // Return the i-th 64-bit word of the number.
- LIBC_INLINE constexpr const uint64_t &operator[](size_t i) const {
- return val[i];
+ LIBC_INLINE constexpr static Division divide_unsigned(const BigInt &dividend,
+ const BigInt &divider) {
+ BigInt remainder = dividend;
+ BigInt quotient;
+ if (remainder >= divider) {
+ BigInt subtractor = divider;
+ int cur_bit = multiword::countl_zero(subtractor.val) -
+ multiword::countl_zero(remainder.val);
+ subtractor <<= cur_bit;
+ for (; cur_bit >= 0 && remainder > 0; --cur_bit, subtractor >>= 1) {
+ if (remainder < subtractor)
+ continue;
+ remainder -= subtractor;
+ quotient.set_bit(cur_bit);
+ }
+ }
+ return Division{quotient, remainder};
}
- // Return the i-th 64-bit word of the number.
- LIBC_INLINE constexpr uint64_t &operator[](size_t i) { return val[i]; }
+ LIBC_INLINE constexpr static Division divide_signed(const BigInt &dividend,
+ const BigInt &divider) {
+ // Special case because it is not possible to negate the min value of a
+ // signed integer.
+ if (dividend == min() && divider == min())
+ return Division{one(), zero()};
+ // 1. Convert the dividend and divisor to unsigned representation.
+ unsigned_type udividend(dividend);
+ unsigned_type udivider(divider);
+ // 2. Negate the dividend if it's negative, and similarly for the divisor.
+ const bool dividend_is_neg = dividend.is_neg();
+ const bool divider_is_neg = divider.is_neg();
+ if (dividend_is_neg)
+ udividend.negate();
+ if (divider_is_neg)
+ udivider.negate();
+ // 3. Use unsigned multiword division algorithm.
+ const auto unsigned_result = divide_unsigned(udividend, udivider);
+ // 4. Convert the quotient and remainder to signed representation.
+ Division result;
+ result.quotient = signed_type(unsigned_result.quotient);
+ result.remainder = signed_type(unsigned_result.remainder);
+ // 5. Negate the quotient if the dividend and divisor had opposite signs.
+ if (dividend_is_neg != divider_is_neg)
+ result.quotient.negate();
+ // 6. Negate the remainder if the dividend was negative.
+ if (dividend_is_neg)
+ result.remainder.negate();
+ return result;
+ }
- LIBC_INLINE uint64_t *data() { return val; }
+ friend signed_type;
+ friend unsigned_type;
+};
- LIBC_INLINE const uint64_t *data() const { return val; }
+namespace internal {
+// We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type
+// availability.
+template <size_t Bits>
+struct WordTypeSelector : cpp::type_identity<
+#ifdef LIBC_TYPES_HAS_INT64
+ uint64_t
+#else
+ uint32_t
+#endif // LIBC_TYPES_HAS_INT64
+ > {
};
+// Except if we request 32 bits explicitly.
+template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
+template <size_t Bits>
+using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;
+} // namespace internal
-template <size_t Bits> using UInt = BigInt<Bits, false>;
+template <size_t Bits>
+using UInt = BigInt<Bits, false, internal::WordTypeSelectorT<Bits>>;
-template <size_t Bits> using Int = BigInt<Bits, true>;
+template <size_t Bits>
+using Int = BigInt<Bits, true, internal::WordTypeSelectorT<Bits>>;
// Provides limits of U/Int<128>.
-template <> class numeric_limits<UInt<128>> {
+template <> class cpp::numeric_limits<UInt<128>> {
public:
- LIBC_INLINE static constexpr UInt<128> max() {
- return UInt<128>({0xffff'ffff'ffff'ffff, 0xffff'ffff'ffff'ffff});
- }
- LIBC_INLINE static constexpr UInt<128> min() { return UInt<128>(0); }
+ LIBC_INLINE static constexpr UInt<128> max() { return UInt<128>::max(); }
+ LIBC_INLINE static constexpr UInt<128> min() { return UInt<128>::min(); }
+ // Meant to match std::numeric_limits interface.
+ // NOLINTNEXTLINE(readability-identifier-naming)
LIBC_INLINE_VAR static constexpr int digits = 128;
};
-template <> class numeric_limits<Int<128>> {
+template <> class cpp::numeric_limits<Int<128>> {
public:
- LIBC_INLINE static constexpr Int<128> max() {
- return Int<128>({0xffff'ffff'ffff'ffff, 0x7fff'ffff'ffff'ffff});
- }
- LIBC_INLINE static constexpr Int<128> min() {
- return Int<128>({0, 0x8000'0000'0000'0000});
- }
+ LIBC_INLINE static constexpr Int<128> max() { return Int<128>::max(); }
+ LIBC_INLINE static constexpr Int<128> min() { return Int<128>::min(); }
+ // Meant to match std::numeric_limits interface.
+ // NOLINTNEXTLINE(readability-identifier-naming)
LIBC_INLINE_VAR static constexpr int digits = 128;
};
-// Provides is_integral of U/Int<128>, U/Int<192>, U/Int<256>.
-template <size_t Bits, bool Signed>
-struct is_integral<BigInt<Bits, Signed>> : cpp::true_type {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in BigInt should be a multiple of 64.");
-};
+// type traits to determine whether a T is a BigInt.
+template <typename T> struct is_big_int : cpp::false_type {};
-// Provides is_unsigned of UInt<128>, UInt<192>, UInt<256>.
-template <size_t Bits> struct is_unsigned<UInt<Bits>> : public cpp::true_type {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in UInt should be a multiple of 64.");
-};
+template <size_t Bits, bool Signed, typename T>
+struct is_big_int<BigInt<Bits, Signed, T>> : cpp::true_type {};
-template <size_t Bits>
-struct make_unsigned<Int<Bits>> : type_identity<UInt<Bits>> {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in Int should be a multiple of 64.");
-};
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int<T>::value;
-template <size_t Bits>
-struct make_unsigned<UInt<Bits>> : type_identity<UInt<Bits>> {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in Int should be a multiple of 64.");
-};
+// extensions of type traits to include BigInt
-template <size_t Bits>
-struct make_signed<Int<Bits>> : type_identity<Int<Bits>> {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in Int should be a multiple of 64.");
-};
+// is_integral_or_big_int
+template <typename T>
+struct is_integral_or_big_int
+ : cpp::bool_constant<(cpp::is_integral_v<T> || is_big_int_v<T>)> {};
-template <size_t Bits>
-struct make_signed<UInt<Bits>> : type_identity<Int<Bits>> {
- static_assert(Bits > 0 && Bits % 64 == 0,
- "Number of bits in Int should be a multiple of 64.");
-};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v =
+ is_integral_or_big_int<T>::value;
-namespace internal {
-template <typename T> struct is_custom_uint : cpp::false_type {};
-template <size_t Bits> struct is_custom_uint<UInt<Bits>> : cpp::true_type {};
-} // namespace internal
+// make_big_int_unsigned
+template <typename T> struct make_big_int_unsigned;
-// bit_cast to UInt
-// Note: The standard scheme for SFINAE selection is to have exactly one
-// function instanciation valid at a time. This is usually done by having a
-// predicate in one function and the negated predicate in the other one.
-// e.g.
-// template<typename = cpp::enable_if_t< is_custom_uint<To>::value == true> ...
-// template<typename = cpp::enable_if_t< is_custom_uint<To>::value == false> ...
-//
-// Unfortunately this would make the default 'cpp::bit_cast' aware of
-// 'is_custom_uint' (or any other customization). To prevent exposing all
-// customizations in the original function, we create a different function with
-// four 'typename's instead of three - otherwise it would be considered as a
-// redeclaration of the same function leading to "error: template parameter
-// redefines default argument".
-template <typename To, typename From,
- typename = cpp::enable_if_t<sizeof(To) == sizeof(From) &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<From>::value>,
- typename = cpp::enable_if_t<internal::is_custom_uint<To>::value>>
-LIBC_INLINE constexpr To bit_cast(const From &from) {
+template <size_t Bits, bool Signed, typename T>
+struct make_big_int_unsigned<BigInt<Bits, Signed, T>>
+ : cpp::type_identity<BigInt<Bits, false, T>> {};
+
+template <typename T>
+using make_big_int_unsigned_t = typename make_big_int_unsigned<T>::type;
+
+// make_big_int_signed
+template <typename T> struct make_big_int_signed;
+
+template <size_t Bits, bool Signed, typename T>
+struct make_big_int_signed<BigInt<Bits, Signed, T>>
+ : cpp::type_identity<BigInt<Bits, true, T>> {};
+
+template <typename T>
+using make_big_int_signed_t = typename make_big_int_signed<T>::type;
+
+// make_integral_or_big_int_unsigned
+template <typename T, class = void> struct make_integral_or_big_int_unsigned;
+
+template <typename T>
+struct make_integral_or_big_int_unsigned<
+ T, cpp::enable_if_t<cpp::is_integral_v<T>>> : cpp::make_unsigned<T> {};
+
+template <typename T>
+struct make_integral_or_big_int_unsigned<T, cpp::enable_if_t<is_big_int_v<T>>>
+ : make_big_int_unsigned<T> {};
+
+template <typename T>
+using make_integral_or_big_int_unsigned_t =
+ typename make_integral_or_big_int_unsigned<T>::type;
+
+// make_integral_or_big_int_signed
+template <typename T, class = void> struct make_integral_or_big_int_signed;
+
+template <typename T>
+struct make_integral_or_big_int_signed<T,
+ cpp::enable_if_t<cpp::is_integral_v<T>>>
+ : cpp::make_signed<T> {};
+
+template <typename T>
+struct make_integral_or_big_int_signed<T, cpp::enable_if_t<is_big_int_v<T>>>
+ : make_big_int_signed<T> {};
+
+template <typename T>
+using make_integral_or_big_int_signed_t =
+ typename make_integral_or_big_int_signed<T>::type;
+
+namespace cpp {
+
+// Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
+template <typename To, typename From>
+LIBC_INLINE constexpr cpp::enable_if_t<
+ (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
+ To>
+bit_cast(const From &from) {
To out;
using Storage = decltype(out.val);
out.val = cpp::bit_cast<Storage>(from);
return out;
}
-// bit_cast from UInt
-template <
- typename To, size_t Bits,
- typename = cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
- cpp::is_trivially_constructible<To>::value &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<UInt<Bits>>::value>>
-LIBC_INLINE constexpr To bit_cast(const UInt<Bits> &from) {
+// Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
+template <typename To, size_t Bits>
+LIBC_INLINE constexpr cpp::enable_if_t<
+ sizeof(To) == sizeof(UInt<Bits>) &&
+ cpp::is_trivially_constructible<To>::value &&
+ cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<UInt<Bits>>::value,
+ To>
+bit_cast(const UInt<Bits> &from) {
return cpp::bit_cast<To>(from.val);
}
-} // namespace LIBC_NAMESPACE::cpp
+// Specialization of cpp::popcount ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+popcount(T value) {
+ int bits = 0;
+ for (auto word : value.val)
+ if (word)
+ bits += popcount(word);
+ return bits;
+}
+
+// Specialization of cpp::has_single_bit ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, bool>
+has_single_bit(T value) {
+ int bits = 0;
+ for (auto word : value.val) {
+ if (word == 0)
+ continue;
+ bits += popcount(word);
+ if (bits > 1)
+ return false;
+ }
+ return bits == 1;
+}
+
+// Specialization of cpp::countr_zero ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+countr_zero(const T &value) {
+ return multiword::countr_zero(value.val);
+}
+
+// Specialization of cpp::countl_zero ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+countl_zero(const T &value) {
+ return multiword::countl_zero(value.val);
+}
+
+// Specialization of cpp::countl_one ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+countl_one(T value) {
+ return multiword::countl_one(value.val);
+}
+
+// Specialization of cpp::countr_one ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+countr_one(T value) {
+ return multiword::countr_one(value.val);
+}
+
+// Specialization of cpp::bit_width ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+bit_width(T value) {
+ return cpp::numeric_limits<T>::digits - cpp::countl_zero(value);
+}
+
+// Forward-declare rotr so that rotl can use it.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+rotr(T value, int rotate);
+
+// Specialization of cpp::rotl ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+rotl(T value, int rotate) {
+ constexpr unsigned N = cpp::numeric_limits<T>::digits;
+ rotate = rotate % N;
+ if (!rotate)
+ return value;
+ if (rotate < 0)
+ return cpp::rotr<T>(value, -rotate);
+ return (value << rotate) | (value >> (N - rotate));
+}
+
+// Specialization of cpp::rotr ('bit.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+rotr(T value, int rotate) {
+ constexpr unsigned N = cpp::numeric_limits<T>::digits;
+ rotate = rotate % N;
+ if (!rotate)
+ return value;
+ if (rotate < 0)
+ return cpp::rotl<T>(value, -rotate);
+ return (value >> rotate) | (value << (N - rotate));
+}
+
+} // namespace cpp
+
+// Specialization of mask_trailing_ones ('math_extras.h') for BigInt.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+mask_trailing_ones() {
+ static_assert(!T::SIGNED && count <= T::BITS);
+ if (count == T::BITS)
+ return T::all_ones();
+ constexpr size_t QUOTIENT = count / T::WORD_SIZE;
+ constexpr size_t REMAINDER = count % T::WORD_SIZE;
+ T out; // zero initialized
+ for (size_t i = 0; i <= QUOTIENT; ++i)
+ out[i] = i < QUOTIENT
+ ? -1
+ : mask_trailing_ones<typename T::word_type, REMAINDER>();
+ return out;
+}
+
+// Specialization of mask_leading_ones ('math_extras.h') for BigInt.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() {
+ static_assert(!T::SIGNED && count <= T::BITS);
+ if (count == T::BITS)
+ return T::all_ones();
+ constexpr size_t QUOTIENT = (T::BITS - count - 1U) / T::WORD_SIZE;
+ constexpr size_t REMAINDER = count % T::WORD_SIZE;
+ T out; // zero initialized
+ for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i)
+ out[i] = i > QUOTIENT
+ ? -1
+ : mask_leading_ones<typename T::word_type, REMAINDER>();
+ return out;
+}
+
+// Specialization of mask_trailing_zeros ('math_extras.h') for BigInt.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+mask_trailing_zeros() {
+ return mask_leading_ones<T, T::BITS - count>();
+}
+
+// Specialization of mask_leading_zeros ('math_extras.h') for BigInt.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
+mask_leading_zeros() {
+ return mask_trailing_ones<T, T::BITS - count>();
+}
+
+// Specialization of count_zeros ('math_extras.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+count_zeros(T value) {
+ return cpp::popcount(~value);
+}
+
+// Specialization of first_leading_zero ('math_extras.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+first_leading_zero(T value) {
+ return value == cpp::numeric_limits<T>::max() ? 0
+ : cpp::countl_one(value) + 1;
+}
+
+// Specialization of first_leading_one ('math_extras.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+first_leading_one(T value) {
+ return first_leading_zero(~value);
+}
+
+// Specialization of first_trailing_zero ('math_extras.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+first_trailing_zero(T value) {
+ return value == cpp::numeric_limits<T>::max() ? 0
+ : cpp::countr_zero(~value) + 1;
+}
+
+// Specialization of first_trailing_one ('math_extras.h') for BigInt.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
+first_trailing_one(T value) {
+ return value == cpp::numeric_limits<T>::max() ? 0
+ : cpp::countr_zero(value) + 1;
+}
+
+} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC___SUPPORT_UINT_H
diff --git a/src/__support/UInt128.h b/src/__support/UInt128.h
index 0558e5095f9f..b6ef9ca18eb0 100644
--- a/src/__support/UInt128.h
+++ b/src/__support/UInt128.h
@@ -10,13 +10,14 @@
#define LLVM_LIBC_SRC___SUPPORT_UINT128_H
#include "UInt.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
-#if defined(__SIZEOF_INT128__)
+#ifdef LIBC_TYPES_HAS_INT128
using UInt128 = __uint128_t;
using Int128 = __int128_t;
#else
-using UInt128 = LIBC_NAMESPACE::cpp::UInt<128>;
-using Int128 = LIBC_NAMESPACE::cpp::Int<128>;
-#endif
+using UInt128 = LIBC_NAMESPACE::UInt<128>;
+using Int128 = LIBC_NAMESPACE::Int<128>;
+#endif // LIBC_TYPES_HAS_INT128
#endif // LLVM_LIBC_SRC___SUPPORT_UINT128_H
diff --git a/src/__support/arg_list.h b/src/__support/arg_list.h
index 9de17651142f..0965e12afd56 100644
--- a/src/__support/arg_list.h
+++ b/src/__support/arg_list.h
@@ -13,6 +13,7 @@
#include <stdarg.h>
#include <stddef.h>
+#include <stdint.h>
namespace LIBC_NAMESPACE {
namespace internal {
@@ -60,6 +61,43 @@ public:
size_t read_count() const { return arg_counter; }
};
+// Used for the GPU implementation of `printf`. This models a variadic list as a
+// simple array of pointers that are built manually by the implementation.
+class StructArgList {
+ void *ptr;
+ void *end;
+
+public:
+ LIBC_INLINE StructArgList(void *ptr, size_t size)
+ : ptr(ptr), end(reinterpret_cast<unsigned char *>(ptr) + size) {}
+ LIBC_INLINE StructArgList(const StructArgList &other) {
+ ptr = other.ptr;
+ end = other.end;
+ }
+ LIBC_INLINE StructArgList() = default;
+ LIBC_INLINE ~StructArgList() = default;
+
+ LIBC_INLINE StructArgList &operator=(const StructArgList &rhs) {
+ ptr = rhs.ptr;
+ return *this;
+ }
+
+ LIBC_INLINE void *get_ptr() const { return ptr; }
+
+ template <class T> LIBC_INLINE T next_var() {
+ ptr = reinterpret_cast<void *>(
+ ((reinterpret_cast<uintptr_t>(ptr) + alignof(T) - 1) / alignof(T)) *
+ alignof(T));
+
+ if (ptr >= end)
+ return T(-1);
+
+ T val = *reinterpret_cast<T *>(ptr);
+ ptr = reinterpret_cast<unsigned char *>(ptr) + sizeof(T);
+ return val;
+ }
+};
+
} // namespace internal
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/blockstore.h b/src/__support/blockstore.h
index d78e4be5fa9c..ac0eb22692b4 100644
--- a/src/__support/blockstore.h
+++ b/src/__support/blockstore.h
@@ -16,7 +16,6 @@
#include <stdint.h>
namespace LIBC_NAMESPACE {
-namespace cpp {
// The difference between BlockStore a traditional vector types is that,
// when more capacity is desired, a new block is added instead of allocating
@@ -45,7 +44,7 @@ protected:
struct Pair {
Block *first, *second;
};
- Pair getLastBlocks() {
+ Pair get_last_blocks() {
if (REVERSE_ORDER)
return {current, current->next};
Block *prev = nullptr;
@@ -56,20 +55,20 @@ protected:
return {curr, prev};
}
- Block *getLastBlock() { return getLastBlocks().first; }
+ Block *get_last_block() { return get_last_blocks().first; }
public:
constexpr BlockStore() = default;
~BlockStore() = default;
- class iterator {
+ class Iterator {
Block *block;
size_t index;
public:
- constexpr iterator(Block *b, size_t i) : block(b), index(i) {}
+ constexpr Iterator(Block *b, size_t i) : block(b), index(i) {}
- iterator &operator++() {
+ Iterator &operator++() {
if (REVERSE_ORDER) {
if (index == 0)
return *this;
@@ -98,11 +97,11 @@ public:
return *reinterpret_cast<T *>(block->data + sizeof(T) * true_index);
}
- bool operator==(const iterator &rhs) const {
+ bool operator==(const Iterator &rhs) const {
return block == rhs.block && index == rhs.index;
}
- bool operator!=(const iterator &rhs) const {
+ bool operator!=(const Iterator &rhs) const {
return block != rhs.block || index != rhs.index;
}
};
@@ -138,7 +137,7 @@ public:
}
T &back() {
- return *reinterpret_cast<T *>(getLastBlock()->data +
+ return *reinterpret_cast<T *>(get_last_block()->data +
sizeof(T) * (fill_count - 1));
}
@@ -146,7 +145,7 @@ public:
fill_count--;
if (fill_count || current == &first)
return;
- auto [last, prev] = getLastBlocks();
+ auto [last, prev] = get_last_blocks();
if (REVERSE_ORDER) {
LIBC_ASSERT(last == current);
current = current->next;
@@ -162,18 +161,18 @@ public:
bool empty() const { return current == &first && !fill_count; }
- iterator begin() {
+ Iterator begin() {
if (REVERSE_ORDER)
- return iterator(current, fill_count);
+ return Iterator(current, fill_count);
else
- return iterator(&first, 0);
+ return Iterator(&first, 0);
}
- iterator end() {
+ Iterator end() {
if (REVERSE_ORDER)
- return iterator(&first, 0);
+ return Iterator(&first, 0);
else
- return iterator(current, fill_count);
+ return Iterator(current, fill_count);
}
};
@@ -203,7 +202,6 @@ void BlockStore<T, BLOCK_SIZE, REVERSE_ORDER>::destroy(
template <typename T, size_t BLOCK_SIZE>
using ReverseOrderBlockStore = BlockStore<T, BLOCK_SIZE, true>;
-} // namespace cpp
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC___SUPPORT_BLOCKSTORE_H
diff --git a/src/__support/char_vector.h b/src/__support/char_vector.h
index 955abdc1fa5a..d39310e09dd7 100644
--- a/src/__support/char_vector.h
+++ b/src/__support/char_vector.h
@@ -11,8 +11,8 @@
#include "src/__support/common.h" // LIBC_INLINE
-#include <stddef.h>
-#include <stdlib.h> // For allocation.
+#include <stddef.h> // size_t
+#include <stdlib.h> // malloc, realloc, free
namespace LIBC_NAMESPACE {
@@ -46,7 +46,7 @@ public:
if (cur_str == local_buffer) {
char *new_str;
new_str = reinterpret_cast<char *>(malloc(cur_buff_size));
- if (new_str == NULL) {
+ if (new_str == nullptr) {
return false;
}
// TODO: replace with inline memcpy
@@ -55,7 +55,7 @@ public:
cur_str = new_str;
} else {
cur_str = reinterpret_cast<char *>(realloc(cur_str, cur_buff_size));
- if (cur_str == NULL) {
+ if (cur_str == nullptr) {
return false;
}
}
diff --git a/src/__support/fixed_point/fx_bits.h b/src/__support/fixed_point/fx_bits.h
new file mode 100644
index 000000000000..53e693d4ddfd
--- /dev/null
+++ b/src/__support/fixed_point/fx_bits.h
@@ -0,0 +1,168 @@
+//===-- Utility class to manipulate fixed point numbers. --*- C++ -*-=========//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_BITS_H
+#define LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_BITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math_extras.h"
+
+#include "fx_rep.h"
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+
+namespace LIBC_NAMESPACE::fixed_point {
+
+template <typename T> struct FXBits {
+private:
+ using fx_rep = FXRep<T>;
+ using StorageType = typename fx_rep::StorageType;
+
+ StorageType value;
+
+ static_assert(fx_rep::FRACTION_LEN > 0);
+
+ static constexpr size_t FRACTION_OFFSET = 0; // Just for completeness
+ static constexpr size_t INTEGRAL_OFFSET =
+ fx_rep::INTEGRAL_LEN == 0 ? 0 : fx_rep::FRACTION_LEN;
+ static constexpr size_t SIGN_OFFSET =
+ fx_rep::SIGN_LEN == 0
+ ? 0
+ : ((sizeof(StorageType) * CHAR_BIT) - fx_rep::SIGN_LEN);
+
+ static constexpr StorageType FRACTION_MASK =
+ mask_trailing_ones<StorageType, fx_rep::FRACTION_LEN>()
+ << FRACTION_OFFSET;
+ static constexpr StorageType INTEGRAL_MASK =
+ mask_trailing_ones<StorageType, fx_rep::INTEGRAL_LEN>()
+ << INTEGRAL_OFFSET;
+ static constexpr StorageType SIGN_MASK =
+ (fx_rep::SIGN_LEN == 0 ? 0 : StorageType(1) << SIGN_OFFSET);
+
+public:
+ LIBC_INLINE constexpr FXBits() = default;
+
+ template <typename XType> LIBC_INLINE constexpr explicit FXBits(XType x) {
+ using Unqual = typename cpp::remove_cv_t<XType>;
+ if constexpr (cpp::is_same_v<Unqual, T>) {
+ value = cpp::bit_cast<StorageType>(x);
+ } else if constexpr (cpp::is_same_v<Unqual, StorageType>) {
+ value = x;
+ } else {
+ // We don't want accidental type promotions/conversions, so we require
+ // exact type match.
+ static_assert(cpp::always_false<XType>);
+ }
+ }
+
+ LIBC_INLINE constexpr StorageType get_fraction() {
+ return (value & FRACTION_MASK) >> FRACTION_OFFSET;
+ }
+
+ LIBC_INLINE constexpr StorageType get_integral() {
+ return (value & INTEGRAL_MASK) >> INTEGRAL_OFFSET;
+ }
+
+ // TODO: replace bool with Sign
+ LIBC_INLINE constexpr bool get_sign() {
+ return static_cast<bool>((value & SIGN_MASK) >> SIGN_OFFSET);
+ }
+
+ // This represents the effective negative exponent applied to this number
+ LIBC_INLINE constexpr int get_exponent() { return fx_rep::FRACTION_LEN; }
+
+ LIBC_INLINE constexpr void set_fraction(StorageType fraction) {
+ value = (value & (~FRACTION_MASK)) |
+ ((fraction << FRACTION_OFFSET) & FRACTION_MASK);
+ }
+
+ LIBC_INLINE constexpr void set_integral(StorageType integral) {
+ value = (value & (~INTEGRAL_MASK)) |
+ ((integral << INTEGRAL_OFFSET) & INTEGRAL_MASK);
+ }
+
+ // TODO: replace bool with Sign
+ LIBC_INLINE constexpr void set_sign(bool sign) {
+ value = (value & (~SIGN_MASK)) |
+ ((static_cast<StorageType>(sign) << SIGN_OFFSET) & SIGN_MASK);
+ }
+
+ LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast<T>(value); }
+};
+
+// Bit-wise operations are not available for fixed point types yet.
+template <typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T>
+bit_and(T x, T y) {
+ using BitType = typename FXRep<T>::StorageType;
+ BitType x_bit = cpp::bit_cast<BitType>(x);
+ BitType y_bit = cpp::bit_cast<BitType>(y);
+ // For some reason, bit_cast cannot deduce BitType from the input.
+ return cpp::bit_cast<T, BitType>(x_bit & y_bit);
+}
+
+template <typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T>
+bit_or(T x, T y) {
+ using BitType = typename FXRep<T>::StorageType;
+ BitType x_bit = cpp::bit_cast<BitType>(x);
+ BitType y_bit = cpp::bit_cast<BitType>(y);
+ // For some reason, bit_cast cannot deduce BitType from the input.
+ return cpp::bit_cast<T, BitType>(x_bit | y_bit);
+}
+
+template <typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T>
+bit_not(T x) {
+ using BitType = typename FXRep<T>::StorageType;
+ BitType x_bit = cpp::bit_cast<BitType>(x);
+ // For some reason, bit_cast cannot deduce BitType from the input.
+ return cpp::bit_cast<T, BitType>(static_cast<BitType>(~x_bit));
+}
+
+template <typename T> LIBC_INLINE constexpr T abs(T x) {
+ using FXRep = FXRep<T>;
+ if constexpr (FXRep::SIGN_LEN == 0)
+ return x;
+ else {
+ if (LIBC_UNLIKELY(x == FXRep::MIN()))
+ return FXRep::MAX();
+ return (x < FXRep::ZERO() ? -x : x);
+ }
+}
+
+// Round-to-nearest, tie-to-(+Inf)
+template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
+ using FXRep = FXRep<T>;
+ if (LIBC_UNLIKELY(n < 0))
+ n = 0;
+ if (LIBC_UNLIKELY(n >= FXRep::FRACTION_LEN))
+ return x;
+
+ T round_bit = FXRep::EPS() << (FXRep::FRACTION_LEN - n - 1);
+ // Check for overflow.
+ if (LIBC_UNLIKELY(FXRep::MAX() - round_bit < x))
+ return FXRep::MAX();
+
+ T all_ones = bit_not(FXRep::ZERO());
+
+ int shift = FXRep::FRACTION_LEN - n;
+ T rounding_mask =
+ (shift == FXRep::TOTAL_LEN) ? FXRep::ZERO() : (all_ones << shift);
+ return bit_and((x + round_bit), rounding_mask);
+}
+
+} // namespace LIBC_NAMESPACE::fixed_point
+
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_BITS_H
diff --git a/src/__support/fixed_point/fx_rep.h b/src/__support/fixed_point/fx_rep.h
new file mode 100644
index 000000000000..f13640a6c019
--- /dev/null
+++ b/src/__support/fixed_point/fx_rep.h
@@ -0,0 +1,300 @@
+//===-- Utility class to manipulate fixed point numbers. --*- C++ -*-=========//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H
+#define LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
+
+#include <stdint.h>
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+
+namespace LIBC_NAMESPACE::fixed_point {
+
+namespace internal {
+
+template <int Bits> struct Storage {
+ static_assert(Bits > 0 && Bits <= 64, "Bits has to be between 1 and 64.");
+ using Type = typename cpp::conditional_t<
+ (Bits <= 8), uint8_t,
+ typename cpp::conditional_t<
+ (Bits <= 16 && Bits > 8), uint16_t,
+ typename cpp::conditional_t<(Bits <= 32 && Bits > 16), uint32_t,
+ uint64_t>>>;
+};
+
+} // namespace internal
+
+template <typename T> struct FXRep;
+
+template <> struct FXRep<short fract> {
+ using Type = short _Fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return SFRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
+ LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HR; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HR; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned short fract> {
+ using Type = unsigned short fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return USFRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }
+ LIBC_INLINE static constexpr Type EPS() { return USFRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHR; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHR; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<fract> {
+ using Type = fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return FRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }
+ LIBC_INLINE static constexpr Type EPS() { return FRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5R; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25R; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned fract> {
+ using Type = unsigned fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return UFRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }
+ LIBC_INLINE static constexpr Type EPS() { return UFRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UR; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UR; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<long fract> {
+ using Type = long fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return LFRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }
+ LIBC_INLINE static constexpr Type EPS() { return LFRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LR; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LR; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned long fract> {
+ using Type = unsigned long fract;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }
+ LIBC_INLINE static constexpr Type EPS() { return ULFRACT_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULR; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULR; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<short accum> {
+ using Type = short accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return SACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }
+ LIBC_INLINE static constexpr Type EPS() { return SACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HK; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HK; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned short accum> {
+ using Type = unsigned short accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return USACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }
+ LIBC_INLINE static constexpr Type EPS() { return USACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHK; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHK; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<accum> {
+ using Type = accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return ACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }
+ LIBC_INLINE static constexpr Type EPS() { return ACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5K; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25K; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned accum> {
+ using Type = unsigned accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return UACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }
+ LIBC_INLINE static constexpr Type EPS() { return UACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UK; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UK; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<long accum> {
+ using Type = long accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return LACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }
+ LIBC_INLINE static constexpr Type EPS() { return LACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LK; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LK; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_signed_t<StorageType>;
+};
+
+template <> struct FXRep<unsigned long accum> {
+ using Type = unsigned long accum;
+
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
+ LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;
+ LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+ SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
+ LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
+ LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MAX; }
+ LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }
+ LIBC_INLINE static constexpr Type EPS() { return ULACCUM_EPSILON; }
+ LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULK; }
+ LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULK; }
+
+ using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+ using CompType = cpp::make_unsigned_t<StorageType>;
+};
+
+template <> struct FXRep<short sat fract> : FXRep<short fract> {};
+template <> struct FXRep<sat fract> : FXRep<fract> {};
+template <> struct FXRep<long sat fract> : FXRep<long fract> {};
+template <>
+struct FXRep<unsigned short sat fract> : FXRep<unsigned short fract> {};
+template <> struct FXRep<unsigned sat fract> : FXRep<unsigned fract> {};
+template <>
+struct FXRep<unsigned long sat fract> : FXRep<unsigned long fract> {};
+
+template <> struct FXRep<short sat accum> : FXRep<short accum> {};
+template <> struct FXRep<sat accum> : FXRep<accum> {};
+template <> struct FXRep<long sat accum> : FXRep<long accum> {};
+template <>
+struct FXRep<unsigned short sat accum> : FXRep<unsigned short accum> {};
+template <> struct FXRep<unsigned sat accum> : FXRep<unsigned accum> {};
+template <>
+struct FXRep<unsigned long sat accum> : FXRep<unsigned long accum> {};
+
+} // namespace LIBC_NAMESPACE::fixed_point
+
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H
diff --git a/src/__support/fixed_point/sqrt.h b/src/__support/fixed_point/sqrt.h
new file mode 100644
index 000000000000..4ec016ceab00
--- /dev/null
+++ b/src/__support/fixed_point/sqrt.h
@@ -0,0 +1,258 @@
+//===-- Calculate square root of fixed point numbers. -----*- C++ -*-=========//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_SQRT_H
+#define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_SQRT_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h" // CHAR_BIT
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+
+#include "fx_rep.h"
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+
+namespace LIBC_NAMESPACE::fixed_point {
+
+namespace internal {
+
+template <typename T> struct SqrtConfig;
+
+template <> struct SqrtConfig<unsigned short fract> {
+ using Type = unsigned short fract;
+ static constexpr int EXTRA_STEPS = 0;
+
+ // Linear approximation for the initial values, with errors bounded by:
+ // max(1.5 * 2^-11, eps)
+ // Generated with Sollya:
+ // > for i from 4 to 15 do {
+ // P = fpminimax(sqrt(x), 1, [|8, 8|], [i * 2^-4, (i + 1)*2^-4],
+ // fixed, absolute);
+ // print("{", coeff(P, 1), "uhr,", coeff(P, 0), "uhr},");
+ // };
+ static constexpr Type FIRST_APPROX[12][2] = {
+ {0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr},
+ {0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr},
+ {0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr},
+ {0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr},
+ {0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr},
+ {0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr},
+ };
+};
+
+template <> struct SqrtConfig<unsigned fract> {
+ using Type = unsigned fract;
+ static constexpr int EXTRA_STEPS = 1;
+
+ // Linear approximation for the initial values, with errors bounded by:
+ // max(1.5 * 2^-11, eps)
+ // Generated with Sollya:
+ // > for i from 4 to 15 do {
+ // P = fpminimax(sqrt(x), 1, [|16, 16|], [i * 2^-4, (i + 1)*2^-4],
+ // fixed, absolute);
+ // print("{", coeff(P, 1), "ur,", coeff(P, 0), "ur},");
+ // };
+ static constexpr Type FIRST_APPROX[12][2] = {
+ {0x1.e378p-1ur, 0x1.0ebp-2ur}, {0x1.b512p-1ur, 0x1.2b94p-2ur},
+ {0x1.91fp-1ur, 0x1.45dcp-2ur}, {0x1.7622p-1ur, 0x1.5e24p-2ur},
+ {0x1.5f5ap-1ur, 0x1.74e4p-2ur}, {0x1.4c58p-1ur, 0x1.8a4p-2ur},
+ {0x1.3c1ep-1ur, 0x1.9e84p-2ur}, {0x1.2e0cp-1ur, 0x1.b1d8p-2ur},
+ {0x1.21aap-1ur, 0x1.c468p-2ur}, {0x1.16bap-1ur, 0x1.d62cp-2ur},
+ {0x1.0cfp-1ur, 0x1.e74cp-2ur}, {0x1.0418p-1ur, 0x1.f7ep-2ur},
+ };
+};
+
+template <> struct SqrtConfig<unsigned long fract> {
+ using Type = unsigned long fract;
+ static constexpr int EXTRA_STEPS = 2;
+
+ // Linear approximation for the initial values, with errors bounded by:
+ // max(1.5 * 2^-11, eps)
+ // Generated with Sollya:
+ // > for i from 4 to 15 do {
+ // P = fpminimax(sqrt(x), 1, [|32, 32|], [i * 2^-4, (i + 1)*2^-4],
+ // fixed, absolute);
+ // print("{", coeff(P, 1), "ulr,", coeff(P, 0), "ulr},");
+ // };
+ static constexpr Type FIRST_APPROX[12][2] = {
+ {0x1.e3779b98p-1ulr, 0x1.0eaff788p-2ulr},
+ {0x1.b5167872p-1ulr, 0x1.2b908ad4p-2ulr},
+ {0x1.91f195cap-1ulr, 0x1.45da800cp-2ulr},
+ {0x1.761ebcb4p-1ulr, 0x1.5e27004cp-2ulr},
+ {0x1.5f619986p-1ulr, 0x1.74db933cp-2ulr},
+ {0x1.4c583adep-1ulr, 0x1.8a3fbfccp-2ulr},
+ {0x1.3c1a591cp-1ulr, 0x1.9e88373cp-2ulr},
+ {0x1.2e08545ap-1ulr, 0x1.b1dd2534p-2ulr},
+ {0x1.21b05c0ap-1ulr, 0x1.c45e023p-2ulr},
+ {0x1.16becd02p-1ulr, 0x1.d624031p-2ulr},
+ {0x1.0cf49fep-1ulr, 0x1.e743b844p-2ulr},
+ {0x1.04214e9cp-1ulr, 0x1.f7ce2c3cp-2ulr},
+ };
+};
+
+template <>
+struct SqrtConfig<unsigned short accum> : SqrtConfig<unsigned fract> {};
+
+template <>
+struct SqrtConfig<unsigned accum> : SqrtConfig<unsigned long fract> {};
+
+// Integer square root
+template <> struct SqrtConfig<unsigned short> {
+ using OutType = unsigned short accum;
+ using FracType = unsigned fract;
+ // For fast-but-less-accurate version
+ using FastFracType = unsigned short fract;
+ using HalfType = unsigned char;
+};
+
+template <> struct SqrtConfig<unsigned int> {
+ using OutType = unsigned accum;
+ using FracType = unsigned long fract;
+ // For fast-but-less-accurate version
+ using FastFracType = unsigned fract;
+ using HalfType = unsigned short;
+};
+
+// TODO: unsigned long accum type is 64-bit, and will need 64-bit fract type.
+// Probably we will use DyadicFloat<64> for intermediate computations instead.
+
+} // namespace internal
+
+// Core computation for sqrt with normalized inputs (0.25 <= x < 1).
+template <typename Config>
+LIBC_INLINE constexpr typename Config::Type
+sqrt_core(typename Config::Type x_frac) {
+ using FracType = typename Config::Type;
+ using FXRep = FXRep<FracType>;
+ using StorageType = typename FXRep::StorageType;
+ // Exact case:
+ if (x_frac == FXRep::ONE_FOURTH())
+ return FXRep::ONE_HALF();
+
+ // Use use Newton method to approximate sqrt(a):
+ // x_{n + 1} = 1/2 (x_n + a / x_n)
+ // For the initial values, we choose x_0
+
+ // Use the leading 4 bits to do look up for sqrt(x).
+ // After normalization, 0.25 <= x_frac < 1, so the leading 4 bits of x_frac
+ // are between 0b0100 and 0b1111. Hence the lookup table only needs 12
+ // entries, and we can get the index by subtracting the leading 4 bits of
+ // x_frac by 4 = 0b0100.
+ StorageType x_bit = cpp::bit_cast<StorageType>(x_frac);
+ int index = (static_cast<int>(x_bit >> (FXRep::TOTAL_LEN - 4))) - 4;
+ FracType a = Config::FIRST_APPROX[index][0];
+ FracType b = Config::FIRST_APPROX[index][1];
+
+ // Initial approximation step.
+ // Estimated error bounds: | r - sqrt(x_frac) | < max(1.5 * 2^-11, eps).
+ FracType r = a * x_frac + b;
+
+ // Further Newton-method iterations for square-root:
+ // x_{n + 1} = 0.5 * (x_n + a / x_n)
+ // We distribute and do the multiplication by 0.5 first to avoid overflow.
+ // TODO: Investigate the performance and accuracy of using division-free
+ // iterations from:
+ // Blanchard, J. D. and Chamberland, M., "Newton's Method Without Division",
+ // The American Mathematical Monthly (2023).
+ // https://chamberland.math.grinnell.edu/papers/newton.pdf
+ for (int i = 0; i < Config::EXTRA_STEPS; ++i)
+ r = (r >> 1) + (x_frac >> 1) / r;
+
+ return r;
+}
+
+template <typename T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T> sqrt(T x) {
+ using BitType = typename FXRep<T>::StorageType;
+ BitType x_bit = cpp::bit_cast<BitType>(x);
+
+ if (LIBC_UNLIKELY(x_bit == 0))
+ return FXRep<T>::ZERO();
+
+ int leading_zeros = cpp::countl_zero(x_bit);
+ constexpr int STORAGE_LENGTH = sizeof(BitType) * CHAR_BIT;
+ constexpr int EXP_ADJUSTMENT = STORAGE_LENGTH - FXRep<T>::FRACTION_LEN - 1;
+ // x_exp is the real exponent of the leading bit of x.
+ int x_exp = EXP_ADJUSTMENT - leading_zeros;
+ int shift = EXP_ADJUSTMENT - 1 - (x_exp & (~1));
+ // Normalize.
+ x_bit <<= shift;
+ using FracType = typename internal::SqrtConfig<T>::Type;
+ FracType x_frac = cpp::bit_cast<FracType>(x_bit);
+
+ // Compute sqrt(x_frac) using Newton-method.
+ FracType r = sqrt_core<internal::SqrtConfig<T>>(x_frac);
+
+ // Re-scaling
+ r >>= EXP_ADJUSTMENT - (x_exp >> 1);
+
+ // Return result.
+ return cpp::bit_cast<T>(r);
+}
+
+// Integer square root - Accurate version:
+// Absolute errors < 2^(-fraction length).
+template <typename T>
+LIBC_INLINE constexpr typename internal::SqrtConfig<T>::OutType isqrt(T x) {
+ using OutType = typename internal::SqrtConfig<T>::OutType;
+ using FracType = typename internal::SqrtConfig<T>::FracType;
+
+ if (x == 0)
+ return FXRep<OutType>::ZERO();
+
+ // Normalize the leading bits to the first two bits.
+ // Shift and then Bit cast x to x_frac gives us:
+ // x = 2^(FRACTION_LEN + 1 - shift) * x_frac;
+ int leading_zeros = cpp::countl_zero(x);
+ int shift = ((leading_zeros >> 1) << 1);
+ x <<= shift;
+ // Convert to frac type and compute square root.
+ FracType x_frac = cpp::bit_cast<FracType>(x);
+ FracType r = sqrt_core<internal::SqrtConfig<FracType>>(x_frac);
+ // To rescale back to the OutType (Accum)
+ r >>= (shift >> 1);
+
+ return cpp::bit_cast<OutType>(r);
+}
+
+// Integer square root - Fast but less accurate version:
+// Relative errors < 2^(-fraction length).
+template <typename T>
+LIBC_INLINE constexpr typename internal::SqrtConfig<T>::OutType
+isqrt_fast(T x) {
+ using OutType = typename internal::SqrtConfig<T>::OutType;
+ using FracType = typename internal::SqrtConfig<T>::FastFracType;
+ using StorageType = typename FXRep<FracType>::StorageType;
+
+ if (x == 0)
+ return FXRep<OutType>::ZERO();
+
+ // Normalize the leading bits to the first two bits.
+ // Shift and then Bit cast x to x_frac gives us:
+ // x = 2^(FRACTION_LEN + 1 - shift) * x_frac;
+ int leading_zeros = cpp::countl_zero(x);
+ int shift = (leading_zeros & (~1));
+ x <<= shift;
+ // Convert to frac type and compute square root.
+ FracType x_frac = cpp::bit_cast<FracType>(
+ static_cast<StorageType>(x >> FXRep<FracType>::FRACTION_LEN));
+ OutType r =
+ static_cast<OutType>(sqrt_core<internal::SqrtConfig<FracType>>(x_frac));
+ // To rescale back to the OutType (Accum)
+ r <<= (FXRep<OutType>::INTEGRAL_LEN - (shift >> 1));
+ return cpp::bit_cast<OutType>(r);
+}
+
+} // namespace LIBC_NAMESPACE::fixed_point
+
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_SQRT_H
diff --git a/src/__support/fixedvector.h b/src/__support/fixedvector.h
index fff905d8c6c4..81747ee10067 100644
--- a/src/__support/fixedvector.h
+++ b/src/__support/fixedvector.h
@@ -11,6 +11,8 @@
#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/iterator.h"
+
namespace LIBC_NAMESPACE {
// A fixed size data store backed by an underlying cpp::array data structure. It
@@ -55,6 +57,12 @@ public:
// matches the `destroy` API of those other data structures so that users
// can easily swap one data structure for the other.
static void destroy(FixedVector<T, CAPACITY> *store) { store->reset(); }
+
+ using reverse_iterator = typename cpp::array<T, CAPACITY>::reverse_iterator;
+ LIBC_INLINE constexpr reverse_iterator rbegin() {
+ return reverse_iterator{&store[item_count]};
+ }
+ LIBC_INLINE constexpr reverse_iterator rend() { return store.rend(); }
};
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/float_to_string.h b/src/__support/float_to_string.h
index 1431aeffa5b2..4c59cfd99c2e 100644
--- a/src/__support/float_to_string.h
+++ b/src/__support/float_to_string.h
@@ -179,8 +179,8 @@ LIBC_INLINE constexpr uint32_t length_for_num(uint32_t idx,
// TODO: Fix long doubles (needs bigger table or alternate algorithm.)
// Currently the table values are generated, which is very slow.
template <size_t INT_SIZE>
-LIBC_INLINE constexpr cpp::UInt<MID_INT_SIZE> get_table_positive(int exponent,
- size_t i) {
+LIBC_INLINE constexpr UInt<MID_INT_SIZE> get_table_positive(int exponent,
+ size_t i) {
// INT_SIZE is the size of int that is used for the internal calculations of
// this function. It should be large enough to hold 2^(exponent+constant), so
// ~1000 for double and ~16000 for long double. Be warned that the time
@@ -191,24 +191,24 @@ LIBC_INLINE constexpr cpp::UInt<MID_INT_SIZE> get_table_positive(int exponent,
if (shift_amount < 0) {
return 1;
}
- cpp::UInt<INT_SIZE> num(0);
+ UInt<INT_SIZE> num(0);
// MOD_SIZE is one of the limiting factors for how big the constant argument
// can get, since it needs to be small enough to fit in the result UInt,
// otherwise we'll get truncation on return.
- constexpr cpp::UInt<INT_SIZE> MOD_SIZE =
- (cpp::UInt<INT_SIZE>(EXP10_9)
+ constexpr UInt<INT_SIZE> MOD_SIZE =
+ (UInt<INT_SIZE>(EXP10_9)
<< (CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0)));
- num = cpp::UInt<INT_SIZE>(1) << (shift_amount);
+ num = UInt<INT_SIZE>(1) << (shift_amount);
if (i > 0) {
- cpp::UInt<INT_SIZE> fives(EXP5_9);
+ UInt<INT_SIZE> fives(EXP5_9);
fives.pow_n(i);
num = num / fives;
}
num = num + 1;
if (num > MOD_SIZE) {
- auto rem = num.div_uint32_times_pow_2(
+ auto rem = num.div_uint_half_times_pow_2(
EXP10_9, CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0))
.value();
num = rem;
@@ -217,8 +217,7 @@ LIBC_INLINE constexpr cpp::UInt<MID_INT_SIZE> get_table_positive(int exponent,
}
template <size_t INT_SIZE>
-LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_positive_df(int exponent,
- size_t i) {
+LIBC_INLINE UInt<MID_INT_SIZE> get_table_positive_df(int exponent, size_t i) {
static_assert(INT_SIZE == 256,
"Only 256 is supported as an int size right now.");
// This version uses dyadic floats with 256 bit mantissas to perform the same
@@ -233,11 +232,11 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_positive_df(int exponent,
return 1;
}
fputil::DyadicFloat<INT_SIZE> num(false, 0, 1);
- constexpr cpp::UInt<INT_SIZE> MOD_SIZE =
- (cpp::UInt<INT_SIZE>(EXP10_9)
+ constexpr UInt<INT_SIZE> MOD_SIZE =
+ (UInt<INT_SIZE>(EXP10_9)
<< (CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0)));
- constexpr cpp::UInt<INT_SIZE> FIVE_EXP_MINUS_NINE_MANT{
+ constexpr UInt<INT_SIZE> FIVE_EXP_MINUS_NINE_MANT{
{0xf387295d242602a7, 0xfdd7645e011abac9, 0x31680a88f8953030,
0x89705f4136b4a597}};
@@ -251,17 +250,17 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_positive_df(int exponent,
num = mul_pow_2(num, shift_amount);
// Adding one is part of the formula.
- cpp::UInt<INT_SIZE> int_num = static_cast<cpp::UInt<INT_SIZE>>(num) + 1;
+ UInt<INT_SIZE> int_num = static_cast<UInt<INT_SIZE>>(num) + 1;
if (int_num > MOD_SIZE) {
auto rem =
int_num
- .div_uint32_times_pow_2(EXP10_9, CALC_SHIFT_CONST +
- (IDX_SIZE > 1 ? IDX_SIZE : 0))
+ .div_uint_half_times_pow_2(
+ EXP10_9, CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0))
.value();
int_num = rem;
}
- cpp::UInt<MID_INT_SIZE> result = int_num;
+ UInt<MID_INT_SIZE> result = int_num;
return result;
}
@@ -275,11 +274,11 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_positive_df(int exponent,
// The formula being used looks more like this:
// floor(10^(9*(-i)) * 2^(c_0 + (-e))) % (10^9 * 2^c_0)
template <size_t INT_SIZE>
-LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i) {
+LIBC_INLINE UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i) {
int shift_amount = CALC_SHIFT_CONST - exponent;
- cpp::UInt<INT_SIZE> num(1);
- constexpr cpp::UInt<INT_SIZE> MOD_SIZE =
- (cpp::UInt<INT_SIZE>(EXP10_9)
+ UInt<INT_SIZE> num(1);
+ constexpr UInt<INT_SIZE> MOD_SIZE =
+ (UInt<INT_SIZE>(EXP10_9)
<< (CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0)));
size_t ten_blocks = i;
@@ -298,12 +297,12 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i) {
}
if (five_blocks > 0) {
- cpp::UInt<INT_SIZE> fives(EXP5_9);
+ UInt<INT_SIZE> fives(EXP5_9);
fives.pow_n(five_blocks);
num = fives;
}
if (ten_blocks > 0) {
- cpp::UInt<INT_SIZE> tens(EXP10_9);
+ UInt<INT_SIZE> tens(EXP10_9);
tens.pow_n(ten_blocks);
if (five_blocks <= 0) {
num = tens;
@@ -318,7 +317,7 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i) {
num = num >> (-shift_amount);
}
if (num > MOD_SIZE) {
- auto rem = num.div_uint32_times_pow_2(
+ auto rem = num.div_uint_half_times_pow_2(
EXP10_9, CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0))
.value();
num = rem;
@@ -327,8 +326,7 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative(int exponent, size_t i) {
}
template <size_t INT_SIZE>
-LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative_df(int exponent,
- size_t i) {
+LIBC_INLINE UInt<MID_INT_SIZE> get_table_negative_df(int exponent, size_t i) {
static_assert(INT_SIZE == 256,
"Only 256 is supported as an int size right now.");
// This version uses dyadic floats with 256 bit mantissas to perform the same
@@ -341,11 +339,11 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative_df(int exponent,
int shift_amount = CALC_SHIFT_CONST - exponent;
fputil::DyadicFloat<INT_SIZE> num(false, 0, 1);
- constexpr cpp::UInt<INT_SIZE> MOD_SIZE =
- (cpp::UInt<INT_SIZE>(EXP10_9)
+ constexpr UInt<INT_SIZE> MOD_SIZE =
+ (UInt<INT_SIZE>(EXP10_9)
<< (CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0)));
- constexpr cpp::UInt<INT_SIZE> TEN_EXP_NINE_MANT(EXP10_9);
+ constexpr UInt<INT_SIZE> TEN_EXP_NINE_MANT(EXP10_9);
static const fputil::DyadicFloat<INT_SIZE> TEN_EXP_NINE(false, 0,
TEN_EXP_NINE_MANT);
@@ -356,26 +354,26 @@ LIBC_INLINE cpp::UInt<MID_INT_SIZE> get_table_negative_df(int exponent,
}
num = mul_pow_2(num, shift_amount);
- cpp::UInt<INT_SIZE> int_num = static_cast<cpp::UInt<INT_SIZE>>(num);
+ UInt<INT_SIZE> int_num = static_cast<UInt<INT_SIZE>>(num);
if (int_num > MOD_SIZE) {
auto rem =
int_num
- .div_uint32_times_pow_2(EXP10_9, CALC_SHIFT_CONST +
- (IDX_SIZE > 1 ? IDX_SIZE : 0))
+ .div_uint_half_times_pow_2(
+ EXP10_9, CALC_SHIFT_CONST + (IDX_SIZE > 1 ? IDX_SIZE : 0))
.value();
int_num = rem;
}
- cpp::UInt<MID_INT_SIZE> result = int_num;
+ UInt<MID_INT_SIZE> result = int_num;
return result;
}
-LIBC_INLINE uint32_t fast_uint_mod_1e9(const cpp::UInt<MID_INT_SIZE> &val) {
+LIBC_INLINE uint32_t fast_uint_mod_1e9(const UInt<MID_INT_SIZE> &val) {
// The formula for mult_const is:
// 1 + floor((2^(bits in target integer size + log_2(divider))) / divider)
// Where divider is 10^9 and target integer size is 128.
- const cpp::UInt<MID_INT_SIZE> mult_const(
+ const UInt<MID_INT_SIZE> mult_const(
{0x31680A88F8953031u, 0x89705F4136B4A597u, 0});
const auto middle = (mult_const * val);
const uint64_t result = static_cast<uint64_t>(middle[2]);
@@ -385,11 +383,12 @@ LIBC_INLINE uint32_t fast_uint_mod_1e9(const cpp::UInt<MID_INT_SIZE> &val) {
}
LIBC_INLINE uint32_t mul_shift_mod_1e9(const FPBits::StorageType mantissa,
- const cpp::UInt<MID_INT_SIZE> &large,
+ const UInt<MID_INT_SIZE> &large,
const int32_t shift_amount) {
- cpp::UInt<MID_INT_SIZE + FPBits::STORAGE_LEN> val(large);
+ UInt<MID_INT_SIZE + FPBits::STORAGE_LEN> val(large);
val = (val * mantissa) >> shift_amount;
- return static_cast<uint32_t>(val.div_uint32_times_pow_2(EXP10_9, 0).value());
+ return static_cast<uint32_t>(
+ val.div_uint_half_times_pow_2(static_cast<uint32_t>(EXP10_9), 0).value());
}
} // namespace internal
@@ -451,7 +450,7 @@ public:
const uint32_t pos_exp = idx * IDX_SIZE;
- cpp::UInt<MID_INT_SIZE> val;
+ UInt<MID_INT_SIZE> val;
#if defined(LIBC_COPT_FLOAT_TO_STR_USE_DYADIC_FLOAT)
// ----------------------- DYADIC FLOAT CALC MODE ------------------------
@@ -501,7 +500,7 @@ public:
if (exponent < 0) {
const int32_t idx = -exponent / IDX_SIZE;
- cpp::UInt<MID_INT_SIZE> val;
+ UInt<MID_INT_SIZE> val;
const uint32_t pos_exp = static_cast<uint32_t>(idx * IDX_SIZE);
@@ -614,7 +613,7 @@ public:
}
};
-#if !defined(LIBC_LONG_DOUBLE_IS_FLOAT64) && \
+#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) && \
!defined(LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD)
// --------------------------- LONG DOUBLE FUNCTIONS ---------------------------
@@ -642,7 +641,7 @@ template <> class FloatToString<long double> {
internal::div_ceil(sizeof(long double) * CHAR_BIT, UINT_WORD_SIZE) *
UINT_WORD_SIZE;
- using wide_int = cpp::UInt<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH>;
+ using wide_int = UInt<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH>;
// float_as_fixed represents the floating point number as a fixed point number
// with the point EXTRA_INT_WIDTH bits from the left of the number. This can
@@ -651,13 +650,14 @@ template <> class FloatToString<long double> {
int int_block_index = 0;
static constexpr size_t BLOCK_BUFFER_LEN =
- internal::div_ceil(internal::log10_pow2(FLOAT_AS_INT_WIDTH), BLOCK_SIZE);
+ internal::div_ceil(internal::log10_pow2(FLOAT_AS_INT_WIDTH), BLOCK_SIZE) +
+ 1;
BlockInt block_buffer[BLOCK_BUFFER_LEN] = {0};
size_t block_buffer_valid = 0;
template <size_t Bits>
- LIBC_INLINE static constexpr BlockInt grab_digits(cpp::UInt<Bits> &int_num) {
- auto wide_result = int_num.div_uint32_times_pow_2(EXP5_9, 9);
+ LIBC_INLINE static constexpr BlockInt grab_digits(UInt<Bits> &int_num) {
+ auto wide_result = int_num.div_uint_half_times_pow_2(EXP5_9, 9);
// the optional only comes into effect when dividing by 0, which will
// never happen here. Thus, we just assert that it has value.
LIBC_ASSERT(wide_result.has_value());
@@ -689,11 +689,13 @@ template <> class FloatToString<long double> {
wide_int float_as_int = mantissa;
- float_as_int.shift_left(exponent);
+ float_as_int <<= exponent;
int_block_index = 0;
while (float_as_int > 0) {
- block_buffer[int_block_index] = grab_digits(float_as_int);
+ LIBC_ASSERT(int_block_index < static_cast<int>(BLOCK_BUFFER_LEN));
+ block_buffer[int_block_index] =
+ grab_digits<FLOAT_AS_INT_WIDTH + EXTRA_INT_WIDTH>(float_as_int);
++int_block_index;
}
block_buffer_valid = int_block_index;
@@ -706,17 +708,18 @@ template <> class FloatToString<long double> {
const int SHIFT_AMOUNT = FLOAT_AS_INT_WIDTH + exponent;
static_assert(EXTRA_INT_WIDTH >= sizeof(long double) * 8);
- float_as_fixed.shift_left(SHIFT_AMOUNT);
+ float_as_fixed <<= SHIFT_AMOUNT;
// If there are still digits above the decimal point, handle those.
- if (float_as_fixed.clz() < EXTRA_INT_WIDTH) {
- cpp::UInt<EXTRA_INT_WIDTH> above_decimal_point =
+ if (cpp::countl_zero(float_as_fixed) <
+ static_cast<int>(EXTRA_INT_WIDTH)) {
+ UInt<EXTRA_INT_WIDTH> above_decimal_point =
float_as_fixed >> FLOAT_AS_INT_WIDTH;
size_t positive_int_block_index = 0;
while (above_decimal_point > 0) {
block_buffer[positive_int_block_index] =
- grab_digits(above_decimal_point);
+ grab_digits<EXTRA_INT_WIDTH>(above_decimal_point);
++positive_int_block_index;
}
block_buffer_valid = positive_int_block_index;
@@ -785,6 +788,8 @@ public:
if (block_index > static_cast<int>(block_buffer_valid) || block_index < 0)
return 0;
+ LIBC_ASSERT(block_index < static_cast<int>(BLOCK_BUFFER_LEN));
+
return block_buffer[block_index];
}
@@ -831,7 +836,7 @@ public:
}
};
-#endif // !LIBC_LONG_DOUBLE_IS_FLOAT64 &&
+#endif // !LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64 &&
// !LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD
} // namespace LIBC_NAMESPACE
diff --git a/src/__support/high_precision_decimal.h b/src/__support/high_precision_decimal.h
index d29f8c4cd932..2c5a349e4495 100644
--- a/src/__support/high_precision_decimal.h
+++ b/src/__support/high_precision_decimal.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
#define LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
+#include "src/__support/CPP/limits.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/str_to_integer.h"
#include <stdint.h>
@@ -115,9 +116,10 @@ class HighPrecisionDecimal {
uint8_t digits[MAX_NUM_DIGITS];
private:
- bool should_round_up(int32_t roundToDigit, RoundDirection round) {
- if (roundToDigit < 0 ||
- static_cast<uint32_t>(roundToDigit) >= this->num_digits) {
+ LIBC_INLINE bool should_round_up(int32_t round_to_digit,
+ RoundDirection round) {
+ if (round_to_digit < 0 ||
+ static_cast<uint32_t>(round_to_digit) >= this->num_digits) {
return false;
}
@@ -133,8 +135,8 @@ private:
// Else round to nearest.
// If we're right in the middle and there are no extra digits
- if (this->digits[roundToDigit] == 5 &&
- static_cast<uint32_t>(roundToDigit + 1) == this->num_digits) {
+ if (this->digits[round_to_digit] == 5 &&
+ static_cast<uint32_t>(round_to_digit + 1) == this->num_digits) {
// Round up if we've truncated (since that means the result is slightly
// higher than what's represented.)
@@ -143,22 +145,22 @@ private:
}
// If this exactly halfway, round to even.
- if (roundToDigit == 0)
+ if (round_to_digit == 0)
// When the input is ".5".
return false;
- return this->digits[roundToDigit - 1] % 2 != 0;
+ return this->digits[round_to_digit - 1] % 2 != 0;
}
- // If there are digits after roundToDigit, they must be non-zero since we
+ // If there are digits after round_to_digit, they must be non-zero since we
// trim trailing zeroes after all operations that change digits.
- return this->digits[roundToDigit] >= 5;
+ return this->digits[round_to_digit] >= 5;
}
// Takes an amount to left shift and returns the number of new digits needed
// to store the result based on LEFT_SHIFT_DIGIT_TABLE.
- uint32_t get_num_new_digits(uint32_t lShiftAmount) {
+ LIBC_INLINE uint32_t get_num_new_digits(uint32_t lshift_amount) {
const char *power_of_five =
- LEFT_SHIFT_DIGIT_TABLE[lShiftAmount].power_of_five;
- uint32_t new_digits = LEFT_SHIFT_DIGIT_TABLE[lShiftAmount].new_digits;
+ LEFT_SHIFT_DIGIT_TABLE[lshift_amount].power_of_five;
+ uint32_t new_digits = LEFT_SHIFT_DIGIT_TABLE[lshift_amount].new_digits;
uint32_t digit_index = 0;
while (power_of_five[digit_index] != 0) {
if (digit_index >= this->num_digits) {
@@ -176,7 +178,7 @@ private:
}
// Trim all trailing 0s
- void trim_trailing_zeroes() {
+ LIBC_INLINE void trim_trailing_zeroes() {
while (this->num_digits > 0 && this->digits[this->num_digits - 1] == 0) {
--this->num_digits;
}
@@ -186,19 +188,19 @@ private:
}
// Perform a digitwise binary non-rounding right shift on this value by
- // shiftAmount. The shiftAmount can't be more than MAX_SHIFT_AMOUNT to prevent
- // overflow.
- void right_shift(uint32_t shiftAmount) {
+ // shift_amount. The shift_amount can't be more than MAX_SHIFT_AMOUNT to
+ // prevent overflow.
+ LIBC_INLINE void right_shift(uint32_t shift_amount) {
uint32_t read_index = 0;
uint32_t write_index = 0;
uint64_t accumulator = 0;
- const uint64_t shift_mask = (uint64_t(1) << shiftAmount) - 1;
+ const uint64_t shift_mask = (uint64_t(1) << shift_amount) - 1;
// Warm Up phase: we don't have enough digits to start writing, so just
// read them into the accumulator.
- while (accumulator >> shiftAmount == 0) {
+ while (accumulator >> shift_amount == 0) {
uint64_t read_digit = 0;
// If there are still digits to read, read the next one, else the digit is
// assumed to be 0.
@@ -217,7 +219,7 @@ private:
// read. Keep reading until we run out of digits.
while (read_index < this->num_digits) {
uint64_t read_digit = this->digits[read_index];
- uint64_t write_digit = accumulator >> shiftAmount;
+ uint64_t write_digit = accumulator >> shift_amount;
accumulator &= shift_mask;
this->digits[write_index] = static_cast<uint8_t>(write_digit);
accumulator = accumulator * 10 + read_digit;
@@ -228,7 +230,7 @@ private:
// Cool Down phase: All of the readable digits have been read, so just write
// the remainder, while treating any more digits as 0.
while (accumulator > 0) {
- uint64_t write_digit = accumulator >> shiftAmount;
+ uint64_t write_digit = accumulator >> shift_amount;
accumulator &= shift_mask;
if (write_index < MAX_NUM_DIGITS) {
this->digits[write_index] = static_cast<uint8_t>(write_digit);
@@ -243,10 +245,10 @@ private:
}
// Perform a digitwise binary non-rounding left shift on this value by
- // shiftAmount. The shiftAmount can't be more than MAX_SHIFT_AMOUNT to prevent
- // overflow.
- void left_shift(uint32_t shiftAmount) {
- uint32_t new_digits = this->get_num_new_digits(shiftAmount);
+ // shift_amount. The shift_amount can't be more than MAX_SHIFT_AMOUNT to
+ // prevent overflow.
+ LIBC_INLINE void left_shift(uint32_t shift_amount) {
+ uint32_t new_digits = this->get_num_new_digits(shift_amount);
int32_t read_index = this->num_digits - 1;
uint32_t write_index = this->num_digits + new_digits;
@@ -260,7 +262,7 @@ private:
// writing.
while (read_index >= 0) {
accumulator += static_cast<uint64_t>(this->digits[read_index])
- << shiftAmount;
+ << shift_amount;
uint64_t next_accumulator = accumulator / 10;
uint64_t write_digit = accumulator - (10 * next_accumulator);
--write_index;
@@ -296,45 +298,52 @@ private:
}
public:
- // numString is assumed to be a string of numeric characters. It doesn't
+ // num_string is assumed to be a string of numeric characters. It doesn't
// handle leading spaces.
- HighPrecisionDecimal(const char *__restrict numString) {
+ LIBC_INLINE
+ HighPrecisionDecimal(
+ const char *__restrict num_string,
+ const size_t num_len = cpp::numeric_limits<size_t>::max()) {
bool saw_dot = false;
+ size_t num_cur = 0;
// This counts the digits in the number, even if there isn't space to store
// them all.
uint32_t total_digits = 0;
- while (isdigit(*numString) || *numString == '.') {
- if (*numString == '.') {
+ while (num_cur < num_len &&
+ (isdigit(num_string[num_cur]) || num_string[num_cur] == '.')) {
+ if (num_string[num_cur] == '.') {
if (saw_dot) {
break;
}
this->decimal_point = total_digits;
saw_dot = true;
} else {
- if (*numString == '0' && this->num_digits == 0) {
+ if (num_string[num_cur] == '0' && this->num_digits == 0) {
--this->decimal_point;
- ++numString;
+ ++num_cur;
continue;
}
++total_digits;
if (this->num_digits < MAX_NUM_DIGITS) {
this->digits[this->num_digits] =
- static_cast<uint8_t>(*numString - '0');
+ static_cast<uint8_t>(num_string[num_cur] - '0');
++this->num_digits;
- } else if (*numString != '0') {
+ } else if (num_string[num_cur] != '0') {
this->truncated = true;
}
}
- ++numString;
+ ++num_cur;
}
if (!saw_dot)
this->decimal_point = total_digits;
- if ((*numString | 32) == 'e') {
- ++numString;
- if (isdigit(*numString) || *numString == '+' || *numString == '-') {
- auto result = strtointeger<int32_t>(numString, 10);
+ if (num_cur < num_len && ((num_string[num_cur] | 32) == 'e')) {
+ ++num_cur;
+ if (isdigit(num_string[num_cur]) || num_string[num_cur] == '+' ||
+ num_string[num_cur] == '-') {
+ auto result =
+ strtointeger<int32_t>(num_string + num_cur, 10, num_len - num_cur);
if (result.has_error()) {
// TODO: handle error
}
@@ -358,33 +367,34 @@ public:
this->trim_trailing_zeroes();
}
- // Binary shift left (shiftAmount > 0) or right (shiftAmount < 0)
- void shift(int shiftAmount) {
- if (shiftAmount == 0) {
+ // Binary shift left (shift_amount > 0) or right (shift_amount < 0)
+ LIBC_INLINE void shift(int shift_amount) {
+ if (shift_amount == 0) {
return;
}
// Left
- else if (shiftAmount > 0) {
- while (static_cast<uint32_t>(shiftAmount) > MAX_SHIFT_AMOUNT) {
+ else if (shift_amount > 0) {
+ while (static_cast<uint32_t>(shift_amount) > MAX_SHIFT_AMOUNT) {
this->left_shift(MAX_SHIFT_AMOUNT);
- shiftAmount -= MAX_SHIFT_AMOUNT;
+ shift_amount -= MAX_SHIFT_AMOUNT;
}
- this->left_shift(shiftAmount);
+ this->left_shift(shift_amount);
}
// Right
else {
- while (static_cast<uint32_t>(shiftAmount) < -MAX_SHIFT_AMOUNT) {
+ while (static_cast<uint32_t>(shift_amount) < -MAX_SHIFT_AMOUNT) {
this->right_shift(MAX_SHIFT_AMOUNT);
- shiftAmount += MAX_SHIFT_AMOUNT;
+ shift_amount += MAX_SHIFT_AMOUNT;
}
- this->right_shift(-shiftAmount);
+ this->right_shift(-shift_amount);
}
}
// Round the number represented to the closest value of unsigned int type T.
// This is done ignoring overflow.
template <class T>
- T round_to_integer_type(RoundDirection round = RoundDirection::Nearest) {
+ LIBC_INLINE T
+ round_to_integer_type(RoundDirection round = RoundDirection::Nearest) {
T result = 0;
uint32_t cur_digit = 0;
@@ -404,10 +414,10 @@ public:
// Extra functions for testing.
- uint8_t *get_digits() { return this->digits; }
- uint32_t get_num_digits() { return this->num_digits; }
- int32_t get_decimal_point() { return this->decimal_point; }
- void set_truncated(bool trunc) { this->truncated = trunc; }
+ LIBC_INLINE uint8_t *get_digits() { return this->digits; }
+ LIBC_INLINE uint32_t get_num_digits() { return this->num_digits; }
+ LIBC_INLINE int32_t get_decimal_point() { return this->decimal_point; }
+ LIBC_INLINE void set_truncated(bool trunc) { this->truncated = trunc; }
};
} // namespace internal
diff --git a/src/__support/integer_literals.h b/src/__support/integer_literals.h
new file mode 100644
index 000000000000..e99799c3512e
--- /dev/null
+++ b/src/__support/integer_literals.h
@@ -0,0 +1,187 @@
+//===-- User literal for unsigned integers ----------------------*- 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 set of user defined literals allows uniform constructions of constants
+// up to 256 bits and also help with unit tests (EXPECT_EQ requires the same
+// type for LHS and RHS).
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H
+#define LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H
+
+#include "src/__support/CPP/limits.h" // CHAR_BIT
+#include "src/__support/UInt128.h" // UInt128
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include <stddef.h> // size_t
+#include <stdint.h> // uintxx_t
+
+namespace LIBC_NAMESPACE {
+
+LIBC_INLINE constexpr uint8_t operator""_u8(unsigned long long value) {
+ return static_cast<uint8_t>(value);
+}
+
+LIBC_INLINE constexpr uint16_t operator""_u16(unsigned long long value) {
+ return static_cast<uint16_t>(value);
+}
+
+LIBC_INLINE constexpr uint32_t operator""_u32(unsigned long long value) {
+ return static_cast<uint32_t>(value);
+}
+
+LIBC_INLINE constexpr uint64_t operator""_u64(unsigned long long value) {
+ return static_cast<uint64_t>(value);
+}
+
+namespace internal {
+
+// Creates a T by reading digits from an array.
+template <typename T>
+LIBC_INLINE constexpr T accumulate(int base, const uint8_t *digits,
+ size_t size) {
+ T value{};
+ for (; size; ++digits, --size) {
+ value *= base;
+ value += *digits;
+ }
+ return value;
+}
+
+// A static buffer to hold the digits for a T.
+template <typename T, int base> struct DigitBuffer {
+ static_assert(base == 2 || base == 10 || base == 16);
+ // One character provides log2(base) bits.
+ // Base 2 and 16 provide exactly one and four bits per character respectively.
+ // For base 10, a character provides log2(10) ≈ 3.32... which we round to 3
+ // for the purpose of buffer allocation.
+ LIBC_INLINE_VAR static constexpr size_t BITS_PER_DIGIT = base == 2 ? 1
+ : base == 10 ? 3
+ : base == 16 ? 4
+ : 0;
+ LIBC_INLINE_VAR static constexpr size_t MAX_DIGITS =
+ sizeof(T) * CHAR_BIT / BITS_PER_DIGIT;
+ LIBC_INLINE_VAR static constexpr uint8_t INVALID_DIGIT = 255;
+
+ uint8_t digits[MAX_DIGITS] = {};
+ size_t size = 0;
+
+ constexpr DigitBuffer(const char *str) {
+ for (; *str != '\0'; ++str)
+ push(*str);
+ }
+
+ // Returns the digit for a particular character.
+ // Returns INVALID_DIGIT if the character is invalid.
+ LIBC_INLINE static constexpr uint8_t get_digit_value(const char c) {
+ const auto to_lower = [](char c) { return c | 32; };
+ const auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
+ const auto is_alpha = [](char c) {
+ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
+ };
+ if (is_digit(c))
+ return static_cast<uint8_t>(c - '0');
+ if (base > 10 && is_alpha(c))
+ return static_cast<uint8_t>(to_lower(c) - 'a' + 10);
+ return INVALID_DIGIT;
+ }
+
+ // Adds a single character to this buffer.
+ LIBC_INLINE constexpr void push(char c) {
+ if (c == '\'')
+ return; // ' is valid but not taken into account.
+ const uint8_t value = get_digit_value(c);
+ if (value == INVALID_DIGIT || size >= MAX_DIGITS) {
+ // During constant evaluation `__builtin_unreachable` will halt the
+ // compiler as it is not executable. This is preferable over `assert` that
+ // will only trigger in debug mode. Also we can't use `static_assert`
+ // because `value` and `size` are not constant.
+ __builtin_unreachable(); // invalid or too many characters.
+ }
+ digits[size] = value;
+ ++size;
+ }
+};
+
+// Generic implementation for native types (including __uint128_t or ExtInt
+// where available).
+template <typename T> struct Parser {
+ template <int base> LIBC_INLINE static constexpr T parse(const char *str) {
+ const DigitBuffer<T, base> buffer(str);
+ return accumulate<T>(base, buffer.digits, buffer.size);
+ }
+};
+
+// Specialization for UInt<N>.
+// Because this code runs at compile time we try to make it efficient. For
+// binary and hexadecimal formats we read digits by chunks of 64 bits and
+// produce the BigInt internal representation direcly. For decimal numbers we
+// go the slow path and use slower BigInt arithmetic.
+template <size_t N> struct Parser<LIBC_NAMESPACE::UInt<N>> {
+ using UIntT = UInt<N>;
+ template <int base> static constexpr UIntT parse(const char *str) {
+ const DigitBuffer<UIntT, base> buffer(str);
+ if constexpr (base == 10) {
+ // Slow path, we sum and multiply BigInt for each digit.
+ return accumulate<UIntT>(base, buffer.digits, buffer.size);
+ } else {
+ // Fast path, we consume blocks of WordType and creates the BigInt's
+ // internal representation directly.
+ using WordArrayT = decltype(UIntT::val);
+ using WordType = typename WordArrayT::value_type;
+ WordArrayT array = {};
+ size_t size = buffer.size;
+ const uint8_t *digit_ptr = buffer.digits + size;
+ for (size_t i = 0; i < array.size(); ++i) {
+ constexpr size_t DIGITS = DigitBuffer<WordType, base>::MAX_DIGITS;
+ const size_t chunk = size > DIGITS ? DIGITS : size;
+ digit_ptr -= chunk;
+ size -= chunk;
+ array[i] = accumulate<WordType>(base, digit_ptr, chunk);
+ }
+ return UIntT(array);
+ }
+ }
+};
+
+// Detects the base of the number and dispatches to the right implementation.
+template <typename T>
+LIBC_INLINE constexpr T parse_with_prefix(const char *ptr) {
+ using P = Parser<T>;
+ if (ptr == nullptr)
+ return T();
+ if (ptr[0] == '0') {
+ if (ptr[1] == 'b')
+ return P::template parse<2>(ptr + 2);
+ if (ptr[1] == 'x')
+ return P::template parse<16>(ptr + 2);
+ }
+ return P::template parse<10>(ptr);
+}
+
+} // namespace internal
+
+LIBC_INLINE constexpr UInt128 operator""_u128(const char *x) {
+ return internal::parse_with_prefix<UInt128>(x);
+}
+
+LIBC_INLINE constexpr auto operator""_u256(const char *x) {
+ return internal::parse_with_prefix<UInt<256>>(x);
+}
+
+template <typename T> LIBC_INLINE constexpr T parse_bigint(const char *ptr) {
+ if (ptr == nullptr)
+ return T();
+ if (ptr[0] == '-' || ptr[0] == '+') {
+ auto positive = internal::parse_with_prefix<T>(ptr + 1);
+ return ptr[0] == '-' ? -positive : positive;
+ }
+ return internal::parse_with_prefix<T>(ptr);
+}
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H
diff --git a/src/__support/integer_to_string.h b/src/__support/integer_to_string.h
index 8d3859c8eb0c..f72d00d1a745 100644
--- a/src/__support/integer_to_string.h
+++ b/src/__support/integer_to_string.h
@@ -67,6 +67,7 @@
#include "src/__support/CPP/span.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/UInt.h" // make_integral_or_big_int_unsigned_t
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
@@ -163,10 +164,10 @@ template <size_t radix> using Custom = details::Fmt<radix>;
// See file header for documentation.
template <typename T, typename Fmt = radix::Dec> class IntegerToString {
- static_assert(cpp::is_integral_v<T>);
+ static_assert(cpp::is_integral_v<T> || is_big_int_v<T>);
LIBC_INLINE static constexpr size_t compute_buffer_size() {
- constexpr auto max_digits = []() -> size_t {
+ constexpr auto MAX_DIGITS = []() -> size_t {
// We size the string buffer for base 10 using an approximation algorithm:
//
// size = ceil(sizeof(T) * 5 / 2)
@@ -188,19 +189,19 @@ template <typename T, typename Fmt = radix::Dec> class IntegerToString {
// For other bases, we approximate by rounding down to the nearest power
// of two base, since the space needed is easy to calculate and it won't
// overestimate by too much.
- constexpr auto floor_log_2 = [](size_t num) -> size_t {
+ constexpr auto FLOOR_LOG_2 = [](size_t num) -> size_t {
size_t i = 0;
for (; num > 1; num /= 2)
++i;
return i;
};
- constexpr size_t BITS_PER_DIGIT = floor_log_2(Fmt::BASE);
+ constexpr size_t BITS_PER_DIGIT = FLOOR_LOG_2(Fmt::BASE);
return ((sizeof(T) * 8 + (BITS_PER_DIGIT - 1)) / BITS_PER_DIGIT);
};
- constexpr size_t digit_size = cpp::max(max_digits(), Fmt::MIN_DIGITS);
- constexpr size_t sign_size = Fmt::BASE == 10 ? 1 : 0;
- constexpr size_t prefix_size = Fmt::PREFIX ? 2 : 0;
- return digit_size + sign_size + prefix_size;
+ constexpr size_t DIGIT_SIZE = cpp::max(MAX_DIGITS(), Fmt::MIN_DIGITS);
+ constexpr size_t SIGN_SIZE = Fmt::BASE == 10 ? 1 : 0;
+ constexpr size_t PREFIX_SIZE = Fmt::PREFIX ? 2 : 0;
+ return DIGIT_SIZE + SIGN_SIZE + PREFIX_SIZE;
}
static constexpr size_t BUFFER_SIZE = compute_buffer_size();
@@ -208,8 +209,8 @@ template <typename T, typename Fmt = radix::Dec> class IntegerToString {
// An internal stateless structure that handles the number formatting logic.
struct IntegerWriter {
- static_assert(cpp::is_integral_v<T>);
- using UNSIGNED_T = cpp::make_unsigned_t<T>;
+ static_assert(cpp::is_integral_v<T> || is_big_int_v<T>);
+ using UNSIGNED_T = make_integral_or_big_int_unsigned_t<T>;
LIBC_INLINE static char digit_char(uint8_t digit) {
if (digit < 10)
diff --git a/src/__support/integer_utils.h b/src/__support/integer_utils.h
deleted file mode 100644
index 1d9a134934cc..000000000000
--- a/src/__support/integer_utils.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===-- Utilities for integers. ---------------------------------*- 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_INTEGER_UTILS_H
-#define LLVM_LIBC_SRC___SUPPORT_INTEGER_UTILS_H
-
-#include "src/__support/CPP/type_traits.h"
-#include "src/__support/common.h"
-
-#include "math_extras.h"
-#include "number_pair.h"
-
-#include <stdint.h>
-
-namespace LIBC_NAMESPACE {
-
-template <typename T> NumberPair<T> full_mul(T a, T b);
-
-template <>
-LIBC_INLINE NumberPair<uint32_t> full_mul<uint32_t>(uint32_t a, uint32_t b) {
- uint64_t prod = uint64_t(a) * uint64_t(b);
- NumberPair<uint32_t> result;
- result.lo = uint32_t(prod);
- result.hi = uint32_t(prod >> 32);
- return result;
-}
-
-template <>
-LIBC_INLINE NumberPair<uint64_t> full_mul<uint64_t>(uint64_t a, uint64_t b) {
-#ifdef __SIZEOF_INT128__
- __uint128_t prod = __uint128_t(a) * __uint128_t(b);
- NumberPair<uint64_t> result;
- result.lo = uint64_t(prod);
- result.hi = uint64_t(prod >> 64);
- return result;
-#else
- NumberPair<uint64_t> pa = split(a);
- NumberPair<uint64_t> pb = split(b);
- NumberPair<uint64_t> prod;
-
- prod.lo = pa.lo * pb.lo; // exact
- prod.hi = pa.hi * pb.hi; // exact
- NumberPair<uint64_t> lo_hi = split(pa.lo * pb.hi); // exact
- NumberPair<uint64_t> hi_lo = split(pa.hi * pb.lo); // exact
-
- auto r1 = add_with_carry(prod.lo, lo_hi.lo << 32, uint64_t(0));
- prod.lo = r1.sum;
- prod.hi = add_with_carry(prod.hi, lo_hi.hi, r1.carry).sum;
-
- auto r2 = add_with_carry(prod.lo, hi_lo.lo << 32, uint64_t(0));
- prod.lo = r2.sum;
- prod.hi = add_with_carry(prod.hi, hi_lo.hi, r2.carry).sum;
-
- return prod;
-#endif // __SIZEOF_INT128__
-}
-
-} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC___SUPPORT_INTEGER_UTILS_H
diff --git a/src/__support/intrusive_list.h b/src/__support/intrusive_list.h
new file mode 100644
index 000000000000..69be877777f7
--- /dev/null
+++ b/src/__support/intrusive_list.h
@@ -0,0 +1,65 @@
+//===-- Intrusive queue implementation. -------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// An intrusive list that implements the insque and remque semantics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H
+#define LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H
+
+#include "common.h"
+
+namespace LIBC_NAMESPACE {
+namespace internal {
+
+class IntrusiveList {
+ struct IntrusiveNodeHeader {
+ IntrusiveNodeHeader *next;
+ IntrusiveNodeHeader *prev;
+ };
+
+public:
+ LIBC_INLINE static void insert(void *elem, void *prev) {
+ auto elem_header = static_cast<IntrusiveNodeHeader *>(elem);
+ auto prev_header = static_cast<IntrusiveNodeHeader *>(prev);
+
+ if (!prev_header) {
+ // The list is linear and elem will be the only element.
+ elem_header->next = nullptr;
+ elem_header->prev = nullptr;
+ return;
+ }
+
+ auto next = prev_header->next;
+
+ elem_header->next = next;
+ elem_header->prev = prev_header;
+
+ prev_header->next = elem_header;
+ if (next)
+ next->prev = elem_header;
+ }
+
+ LIBC_INLINE static void remove(void *elem) {
+ auto elem_header = static_cast<IntrusiveNodeHeader *>(elem);
+
+ auto prev = elem_header->prev;
+ auto next = elem_header->next;
+
+ if (prev)
+ prev->next = next;
+ if (next)
+ next->prev = prev;
+ }
+};
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H
diff --git a/src/__support/macros/config.h b/src/__support/macros/config.h
index fcc8f551a783..6390c7992325 100644
--- a/src/__support/macros/config.h
+++ b/src/__support/macros/config.h
@@ -13,22 +13,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
-// LIBC_HAS_BUILTIN()
-//
-// Checks whether the compiler supports a Clang Feature Checking Macro, and if
-// so, checks whether it supports the provided builtin function "x" where x
-// is one of the functions noted in
-// https://clang.llvm.org/docs/LanguageExtensions.html
-//
-// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check.
-// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html
-
-// Compiler builtin-detection.
-// clang.llvm.org/docs/LanguageExtensions.html#has-builtin
-#ifdef __has_builtin
-#define LIBC_HAS_BUILTIN(x) __has_builtin(x)
-#else
-#define LIBC_HAS_BUILTIN(x) 0
+// Workaround for compilers that do not support builtin detection.
+// FIXME: This is only required for the GPU portion which should be moved.
+#ifndef __has_builtin
+#define __has_builtin(b) 0
#endif
// Compiler feature-detection.
@@ -39,12 +27,4 @@
#define LIBC_HAS_FEATURE(f) 0
#endif
-// Compiler attribute-detection.
-// https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
-#ifdef __has_attribute
-#define LIBC_HAS_ATTRIBUTE(f) __has_attribute(f)
-#else
-#define LIBC_HAS_ATTRIBUTE(f) 0
-#endif
-
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
diff --git a/src/__support/macros/optimization.h b/src/__support/macros/optimization.h
index ae97efcaa417..59886ca44be1 100644
--- a/src/__support/macros/optimization.h
+++ b/src/__support/macros/optimization.h
@@ -11,7 +11,6 @@
#define LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
#include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
// We use a template to implement likely/unlikely to make sure that we don't
diff --git a/src/__support/macros/properties/float.h b/src/__support/macros/properties/float.h
deleted file mode 100644
index 98ca2a5d4bc4..000000000000
--- a/src/__support/macros/properties/float.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- Float type support --------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-// Floating point properties are a combination of compiler support, target OS
-// and target architecture.
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FLOAT_H
-#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FLOAT_H
-
-#include "src/__support/macros/properties/architectures.h"
-#include "src/__support/macros/properties/compiler.h"
-#include "src/__support/macros/properties/cpu_features.h"
-#include "src/__support/macros/properties/os.h"
-
-#include <float.h> // LDBL_MANT_DIG
-
-// 'long double' properties.
-#if (LDBL_MANT_DIG == 53)
-#define LIBC_LONG_DOUBLE_IS_FLOAT64
-#elif (LDBL_MANT_DIG == 64)
-#define LIBC_LONG_DOUBLE_IS_X86_FLOAT80
-#elif (LDBL_MANT_DIG == 113)
-#define LIBC_LONG_DOUBLE_IS_FLOAT128
-#endif
-
-// float16 support.
-#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1500)) || \
- (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1201))
-#define LIBC_COMPILER_HAS_C23_FLOAT16
-#endif
-#endif
-#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 900)) || \
- (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
-#define LIBC_COMPILER_HAS_C23_FLOAT16
-#endif
-#endif
-#if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1300)) || \
- (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
-#define LIBC_COMPILER_HAS_C23_FLOAT16
-#endif
-#endif
-
-#if defined(LIBC_COMPILER_HAS_C23_FLOAT16)
-using float16 = _Float16;
-#define LIBC_HAS_FLOAT16
-#endif
-
-// float128 support.
-#if (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301)) && \
- (defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
- defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) || \
- defined(LIBC_TARGET_ARCH_IS_X86_64))
-#define LIBC_COMPILER_HAS_C23_FLOAT128
-#endif
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 600)) && \
- (defined(LIBC_TARGET_ARCH_IS_X86_64) && \
- defined(LIBC_TARGET_OS_IS_LINUX) && !defined(LIBC_TARGET_OS_IS_FUCHSIA))
-#define LIBC_COMPILER_HAS_FLOAT128_EXTENSION
-#endif
-
-#if defined(LIBC_COMPILER_HAS_C23_FLOAT128)
-using float128 = _Float128;
-#elif defined(LIBC_COMPILER_HAS_FLOAT128_EXTENSION)
-using float128 = __float128;
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT128)
-using float128 = long double;
-#endif
-
-#if defined(LIBC_COMPILER_HAS_C23_FLOAT128) || \
- defined(LIBC_COMPILER_HAS_FLOAT128_EXTENSION) || \
- defined(LIBC_LONG_DOUBLE_IS_FLOAT128)
-// TODO: Replace with LIBC_HAS_FLOAT128
-#define LIBC_COMPILER_HAS_FLOAT128
-#endif
-
-#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FLOAT_H
diff --git a/src/__support/macros/properties/types.h b/src/__support/macros/properties/types.h
new file mode 100644
index 000000000000..d43cf99e6859
--- /dev/null
+++ b/src/__support/macros/properties/types.h
@@ -0,0 +1,69 @@
+//===-- Types support -------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+// Types detection and support.
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
+#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
+
+#include "include/llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
+#include "include/llvm-libc-types/float128.h" // float128
+#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/macros/properties/os.h"
+
+#include <stdint.h> // UINT64_MAX, __SIZEOF_INT128__
+
+// 'long double' properties.
+#if (LDBL_MANT_DIG == 53)
+#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
+#elif (LDBL_MANT_DIG == 64)
+#define LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+#elif (LDBL_MANT_DIG == 113)
+#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
+#endif
+
+// int64 / uint64 support
+#if defined(UINT64_MAX)
+#define LIBC_TYPES_HAS_INT64
+#endif // UINT64_MAX
+
+// int128 / uint128 support
+#if defined(__SIZEOF_INT128__)
+#define LIBC_TYPES_HAS_INT128
+#endif // defined(__SIZEOF_INT128__)
+
+// -- float16 support ---------------------------------------------------------
+// TODO: move this logic to "llvm-libc-types/float16.h"
+#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1500)) || \
+ (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1201))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 900)) || \
+ (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+#if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1300)) || \
+ (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+
+// -- float128 support --------------------------------------------------------
+// LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
+// "include/llvm-libc-types/float128.h"
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
diff --git a/src/__support/macros/sanitizer.h b/src/__support/macros/sanitizer.h
index fc66c2005c42..bd9b62b7121a 100644
--- a/src/__support/macros/sanitizer.h
+++ b/src/__support/macros/sanitizer.h
@@ -47,8 +47,7 @@
// Functions to unpoison memory
//-----------------------------------------------------------------------------
-#if defined(LIBC_HAVE_MEMORY_SANITIZER) && \
- LIBC_HAS_BUILTIN(__builtin_constant_p)
+#if defined(LIBC_HAVE_MEMORY_SANITIZER) && __has_builtin(__builtin_constant_p)
// Only perform MSAN unpoison in non-constexpr context.
#include <sanitizer/msan_interface.h>
#define MSAN_UNPOISON(addr, size) \
diff --git a/src/__support/math_extras.h b/src/__support/math_extras.h
index 8ec30396ffdb..4bd871957406 100644
--- a/src/__support/math_extras.h
+++ b/src/__support/math_extras.h
@@ -10,187 +10,151 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
-#include "src/__support/CPP/limits.h" // CHAR_BIT
-#include "src/__support/CPP/type_traits.h" // is_unsigned_v
+#include "src/__support/CPP/bit.h" // countl_one, countr_zero
+#include "src/__support/CPP/limits.h" // CHAR_BIT, numeric_limits
+#include "src/__support/CPP/type_traits.h" // is_unsigned_v, is_constant_evaluated
#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
namespace LIBC_NAMESPACE {
// Create a bitmask with the count right-most bits set to 1, and all other bits
// set to 0. Only unsigned types are allowed.
template <typename T, size_t count>
-LIBC_INLINE constexpr T mask_trailing_ones() {
- static_assert(cpp::is_unsigned_v<T>);
- constexpr unsigned t_bits = CHAR_BIT * sizeof(T);
- static_assert(count <= t_bits && "Invalid bit index");
- // It's important not to initialize T with -1, since T may be BigInt which
- // will take -1 as a uint64_t and only initialize the low 64 bits.
- constexpr T all_zeroes(0);
- constexpr T all_ones(~all_zeroes); // bitwise NOT performs integer promotion.
- return count == 0 ? 0 : (all_ones >> (t_bits - count));
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+mask_trailing_ones() {
+ constexpr unsigned T_BITS = CHAR_BIT * sizeof(T);
+ static_assert(count <= T_BITS && "Invalid bit index");
+ return count == 0 ? 0 : (T(-1) >> (T_BITS - count));
}
// Create a bitmask with the count left-most bits set to 1, and all other bits
// set to 0. Only unsigned types are allowed.
template <typename T, size_t count>
-LIBC_INLINE constexpr T mask_leading_ones() {
- constexpr T mask(mask_trailing_ones<T, CHAR_BIT * sizeof(T) - count>());
- return T(~mask); // bitwise NOT performs integer promotion.
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+mask_leading_ones() {
+ return T(~mask_trailing_ones<T, CHAR_BIT * sizeof(T) - count>());
}
-// Add with carry
-template <typename T> struct SumCarry {
- T sum;
- T carry;
-};
-
-// This version is always valid for constexpr.
-template <typename T>
-LIBC_INLINE constexpr cpp::enable_if_t<
- cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, SumCarry<T>>
-add_with_carry_const(T a, T b, T carry_in) {
- T tmp = a + carry_in;
- T sum = b + tmp;
- T carry_out = (sum < b) + (tmp < a);
- return {sum, carry_out};
-}
-
-// This version is not always valid for constepxr because it's overriden below
-// if builtins are available.
-template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
- SumCarry<T>>
-add_with_carry(T a, T b, T carry_in) {
- return add_with_carry_const<T>(a, b, carry_in);
-}
-
-#if LIBC_HAS_BUILTIN(__builtin_addc)
-// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
-
-template <>
-LIBC_INLINE SumCarry<unsigned char>
-add_with_carry<unsigned char>(unsigned char a, unsigned char b,
- unsigned char carry_in) {
- SumCarry<unsigned char> result{0, 0};
- result.sum = __builtin_addcb(a, b, carry_in, &result.carry);
- return result;
-}
-
-template <>
-LIBC_INLINE SumCarry<unsigned short>
-add_with_carry<unsigned short>(unsigned short a, unsigned short b,
- unsigned short carry_in) {
- SumCarry<unsigned short> result{0, 0};
- result.sum = __builtin_addcs(a, b, carry_in, &result.carry);
- return result;
+// Create a bitmask with the count right-most bits set to 0, and all other bits
+// set to 1. Only unsigned types are allowed.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+mask_trailing_zeros() {
+ return mask_leading_ones<T, CHAR_BIT * sizeof(T) - count>();
}
-template <>
-LIBC_INLINE SumCarry<unsigned int>
-add_with_carry<unsigned int>(unsigned int a, unsigned int b,
- unsigned int carry_in) {
- SumCarry<unsigned int> result{0, 0};
- result.sum = __builtin_addc(a, b, carry_in, &result.carry);
- return result;
+// Create a bitmask with the count left-most bits set to 0, and all other bits
+// set to 1. Only unsigned types are allowed.
+template <typename T, size_t count>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+mask_leading_zeros() {
+ return mask_trailing_ones<T, CHAR_BIT * sizeof(T) - count>();
}
-template <>
-LIBC_INLINE SumCarry<unsigned long>
-add_with_carry<unsigned long>(unsigned long a, unsigned long b,
- unsigned long carry_in) {
- SumCarry<unsigned long> result{0, 0};
- result.sum = __builtin_addcl(a, b, carry_in, &result.carry);
- return result;
+// Returns whether 'a + b' overflows, the result is stored in 'res'.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr bool add_overflow(T a, T b, T &res) {
+ return __builtin_add_overflow(a, b, &res);
}
-template <>
-LIBC_INLINE SumCarry<unsigned long long>
-add_with_carry<unsigned long long>(unsigned long long a, unsigned long long b,
- unsigned long long carry_in) {
- SumCarry<unsigned long long> result{0, 0};
- result.sum = __builtin_addcll(a, b, carry_in, &result.carry);
- return result;
+// Returns whether 'a - b' overflows, the result is stored in 'res'.
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr bool sub_overflow(T a, T b, T &res) {
+ return __builtin_sub_overflow(a, b, &res);
}
-#endif // LIBC_HAS_BUILTIN(__builtin_addc)
-
-// Subtract with borrow
-template <typename T> struct DiffBorrow {
- T diff;
- T borrow;
-};
+#define RETURN_IF(TYPE, BUILTIN) \
+ if constexpr (cpp::is_same_v<T, TYPE>) \
+ return BUILTIN(a, b, carry_in, carry_out);
-// This version is always valid for constexpr.
+// Returns the result of 'a + b' taking into account 'carry_in'.
+// The carry out is stored in 'carry_out' it not 'nullptr', dropped otherwise.
+// We keep the pass by pointer interface for consistency with the intrinsic.
template <typename T>
-LIBC_INLINE constexpr cpp::enable_if_t<
- cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, DiffBorrow<T>>
-sub_with_borrow_const(T a, T b, T borrow_in) {
- T tmp = a - b;
- T diff = tmp - borrow_in;
- T borrow_out = (diff > tmp) + (tmp > a);
- return {diff, borrow_out};
-}
-
-// This version is not always valid for constepxr because it's overriden below
-// if builtins are available.
+[[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 __has_builtin(__builtin_addcb)
+ RETURN_IF(unsigned char, __builtin_addcb)
+#elif __has_builtin(__builtin_addcs)
+ RETURN_IF(unsigned short, __builtin_addcs)
+#elif __has_builtin(__builtin_addc)
+ RETURN_IF(unsigned int, __builtin_addc)
+#elif __has_builtin(__builtin_addcl)
+ RETURN_IF(unsigned long, __builtin_addcl)
+#elif __has_builtin(__builtin_addcll)
+ RETURN_IF(unsigned long long, __builtin_addcll)
+#endif
+ }
+ T sum = {};
+ T carry1 = add_overflow(a, b, sum);
+ T carry2 = add_overflow(sum, carry_in, sum);
+ carry_out = carry1 | carry2;
+ return sum;
+}
+
+// Returns the result of 'a - b' taking into account 'carry_in'.
+// The carry out is stored in 'carry_out' it not 'nullptr', dropped otherwise.
+// We keep the pass by pointer interface for consistency with the intrinsic.
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
- DiffBorrow<T>>
-sub_with_borrow(T a, T b, T borrow_in) {
- return sub_with_borrow_const<T>(a, b, borrow_in);
-}
-
-#if LIBC_HAS_BUILTIN(__builtin_subc)
-// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
+[[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 __has_builtin(__builtin_subcb)
+ RETURN_IF(unsigned char, __builtin_subcb)
+#elif __has_builtin(__builtin_subcs)
+ RETURN_IF(unsigned short, __builtin_subcs)
+#elif __has_builtin(__builtin_subc)
+ RETURN_IF(unsigned int, __builtin_subc)
+#elif __has_builtin(__builtin_subcl)
+ RETURN_IF(unsigned long, __builtin_subcl)
+#elif __has_builtin(__builtin_subcll)
+ RETURN_IF(unsigned long long, __builtin_subcll)
+#endif
+ }
+ T sub = {};
+ T carry1 = sub_overflow(a, b, sub);
+ T carry2 = sub_overflow(sub, carry_in, sub);
+ carry_out = carry1 | carry2;
+ return sub;
+}
+
+#undef RETURN_IF
-template <>
-LIBC_INLINE DiffBorrow<unsigned char>
-sub_with_borrow<unsigned char>(unsigned char a, unsigned char b,
- unsigned char borrow_in) {
- DiffBorrow<unsigned char> result{0, 0};
- result.diff = __builtin_subcb(a, b, borrow_in, &result.borrow);
- return result;
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+first_leading_zero(T value) {
+ return value == cpp::numeric_limits<T>::max() ? 0
+ : cpp::countl_one(value) + 1;
}
-template <>
-LIBC_INLINE DiffBorrow<unsigned short>
-sub_with_borrow<unsigned short>(unsigned short a, unsigned short b,
- unsigned short borrow_in) {
- DiffBorrow<unsigned short> result{0, 0};
- result.diff = __builtin_subcs(a, b, borrow_in, &result.borrow);
- return result;
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+first_leading_one(T value) {
+ return first_leading_zero(static_cast<T>(~value));
}
-template <>
-LIBC_INLINE DiffBorrow<unsigned int>
-sub_with_borrow<unsigned int>(unsigned int a, unsigned int b,
- unsigned int borrow_in) {
- DiffBorrow<unsigned int> result{0, 0};
- result.diff = __builtin_subc(a, b, borrow_in, &result.borrow);
- return result;
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+first_trailing_zero(T value) {
+ return value == cpp::numeric_limits<T>::max()
+ ? 0
+ : cpp::countr_zero(static_cast<T>(~value)) + 1;
}
-template <>
-LIBC_INLINE DiffBorrow<unsigned long>
-sub_with_borrow<unsigned long>(unsigned long a, unsigned long b,
- unsigned long borrow_in) {
- DiffBorrow<unsigned long> result{0, 0};
- result.diff = __builtin_subcl(a, b, borrow_in, &result.borrow);
- return result;
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+first_trailing_one(T value) {
+ return value == cpp::numeric_limits<T>::max() ? 0
+ : cpp::countr_zero(value) + 1;
}
-template <>
-LIBC_INLINE DiffBorrow<unsigned long long>
-sub_with_borrow<unsigned long long>(unsigned long long a, unsigned long long b,
- unsigned long long borrow_in) {
- DiffBorrow<unsigned long long> result{0, 0};
- result.diff = __builtin_subcll(a, b, borrow_in, &result.borrow);
- return result;
+template <typename T>
+[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
+count_zeros(T value) {
+ return cpp::popcount<T>(static_cast<T>(~value));
}
-#endif // LIBC_HAS_BUILTIN(__builtin_subc)
-
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
diff --git a/src/__support/memory_size.h b/src/__support/memory_size.h
index 4c7d2079553e..491123bbabf3 100644
--- a/src/__support/memory_size.h
+++ b/src/__support/memory_size.h
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC___SUPPORT_MEMORY_SIZE_H
+#define LLVM_LIBC_SRC___SUPPORT_MEMORY_SIZE_H
+
#include "src/__support/CPP/bit.h" // has_single_bit
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/type_traits.h"
@@ -16,7 +19,7 @@
namespace LIBC_NAMESPACE {
namespace internal {
template <class T> LIBC_INLINE bool mul_overflow(T a, T b, T *res) {
-#if LIBC_HAS_BUILTIN(__builtin_mul_overflow)
+#if __has_builtin(__builtin_mul_overflow)
return __builtin_mul_overflow(a, b, res);
#else
T max = cpp::numeric_limits<T>::max();
@@ -52,9 +55,11 @@ public:
LIBC_INLINE SafeMemSize operator+(const SafeMemSize &other) {
type result;
- if (LIBC_UNLIKELY((value | other.value) < 0))
+ if (LIBC_UNLIKELY((value | other.value) < 0)) {
result = -1;
- result = value + other.value;
+ } else {
+ result = value + other.value;
+ }
return SafeMemSize{result};
}
@@ -81,3 +86,5 @@ public:
};
} // namespace internal
} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MEMORY_SIZE_H
diff --git a/src/__support/number_pair.h b/src/__support/number_pair.h
index 12e730836af2..2f713fc03520 100644
--- a/src/__support/number_pair.h
+++ b/src/__support/number_pair.h
@@ -16,21 +16,10 @@
namespace LIBC_NAMESPACE {
template <typename T> struct NumberPair {
- T lo;
- T hi;
+ T lo = T(0);
+ T hi = T(0);
};
-template <typename T>
-cpp::enable_if_t<cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, NumberPair<T>>
-split(T a) {
- constexpr size_t HALF_BIT_WIDTH = sizeof(T) * 4;
- constexpr T LOWER_HALF_MASK = (T(1) << HALF_BIT_WIDTH) - T(1);
- NumberPair<T> result;
- result.lo = a & LOWER_HALF_MASK;
- result.hi = a >> HALF_BIT_WIDTH;
- return result;
-}
-
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC___SUPPORT_NUMBER_PAIR_H
diff --git a/src/__support/sign.h b/src/__support/sign.h
new file mode 100644
index 000000000000..28cfae4bab1d
--- /dev/null
+++ b/src/__support/sign.h
@@ -0,0 +1,40 @@
+//===-- A simple sign type --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_SIGN_H
+#define LLVM_LIBC_SRC___SUPPORT_SIGN_H
+
+#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
+
+// A type to interact with signed arithmetic types.
+struct Sign {
+ LIBC_INLINE constexpr bool is_pos() const { return !is_negative; }
+ LIBC_INLINE constexpr bool is_neg() const { return is_negative; }
+
+ LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) {
+ return a.is_negative == b.is_negative;
+ }
+
+ LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) {
+ return !(a == b);
+ }
+
+ static const Sign POS;
+ static const Sign NEG;
+
+private:
+ LIBC_INLINE constexpr explicit Sign(bool is_negative)
+ : is_negative(is_negative) {}
+
+ bool is_negative;
+};
+
+LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true);
+LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false);
+
+#endif // LLVM_LIBC_SRC___SUPPORT_SIGN_H
diff --git a/src/__support/str_to_float.h b/src/__support/str_to_float.h
index f681fcab7a63..f622b7edaa8a 100644
--- a/src/__support/str_to_float.h
+++ b/src/__support/str_to_float.h
@@ -51,13 +51,13 @@ template <class T> LIBC_INLINE void set_implicit_bit(fputil::FPBits<T> &) {
return;
}
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <>
LIBC_INLINE void
set_implicit_bit<long double>(fputil::FPBits<long double> &result) {
result.set_implicit_bit(result.get_biased_exponent() != 0);
}
-#endif
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
// This Eisel-Lemire implementation is based on the algorithm described in the
// paper Number Parsing at a Gigabyte per Second, Software: Practice and
@@ -176,7 +176,7 @@ eisel_lemire(ExpandedFloat<T> init_num,
return output;
}
-#if !defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
template <>
LIBC_INLINE cpp::optional<ExpandedFloat<long double>>
eisel_lemire<long double>(ExpandedFloat<long double> init_num,
@@ -297,7 +297,7 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
output.exponent = exp2;
return output;
}
-#endif
+#endif // !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
// The nth item in POWERS_OF_TWO represents the greatest power of two less than
// 10^n. This tells us how much we can safely shift without overshooting.
@@ -313,14 +313,15 @@ constexpr int32_t NUM_POWERS_OF_TWO =
// on the Simple Decimal Conversion algorithm by Nigel Tao, described at this
// link: https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
template <class T>
-LIBC_INLINE FloatConvertReturn<T>
-simple_decimal_conversion(const char *__restrict numStart,
- RoundDirection round = RoundDirection::Nearest) {
+LIBC_INLINE FloatConvertReturn<T> simple_decimal_conversion(
+ const char *__restrict numStart,
+ const size_t num_len = cpp::numeric_limits<size_t>::max(),
+ RoundDirection round = RoundDirection::Nearest) {
using FPBits = typename fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
int32_t exp2 = 0;
- HighPrecisionDecimal hpd = HighPrecisionDecimal(numStart);
+ HighPrecisionDecimal hpd = HighPrecisionDecimal(numStart, num_len);
FloatConvertReturn<T> output;
@@ -460,7 +461,7 @@ public:
static constexpr double MAX_EXACT_INT = 9007199254740991.0;
};
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
template <> class ClingerConsts<long double> {
public:
static constexpr long double POWERS_OF_TEN_ARRAY[] = {
@@ -473,7 +474,7 @@ public:
static constexpr long double MAX_EXACT_INT =
ClingerConsts<double>::MAX_EXACT_INT;
};
-#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <> class ClingerConsts<long double> {
public:
static constexpr long double POWERS_OF_TEN_ARRAY[] = {
@@ -484,7 +485,7 @@ public:
static constexpr int32_t DIGITS_IN_MANTISSA = 21;
static constexpr long double MAX_EXACT_INT = 18446744073709551615.0L;
};
-#else
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
template <> class ClingerConsts<long double> {
public:
static constexpr long double POWERS_OF_TEN_ARRAY[] = {
@@ -498,6 +499,8 @@ public:
static constexpr long double MAX_EXACT_INT =
10384593717069655257060992658440191.0L;
};
+#else
+#error "Unknown long double type"
#endif
// Take an exact mantissa and exponent and attempt to convert it using only
@@ -510,7 +513,6 @@ clinger_fast_path(ExpandedFloat<T> init_num,
RoundDirection round = RoundDirection::Nearest) {
using FPBits = typename fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = fputil::Sign;
StorageType mantissa = init_num.mantissa;
int32_t exp10 = init_num.exponent;
@@ -521,7 +523,7 @@ clinger_fast_path(ExpandedFloat<T> init_num,
FPBits result;
T float_mantissa;
- if constexpr (cpp::is_same_v<StorageType, cpp::UInt<128>>) {
+ if constexpr (cpp::is_same_v<StorageType, UInt<128>>) {
float_mantissa = static_cast<T>(fputil::DyadicFloat<128>(
Sign::POS, 0,
fputil::DyadicFloat<128>::MantissaType(
@@ -598,13 +600,17 @@ clinger_fast_path(ExpandedFloat<T> init_num,
// non-inf result for this size of float. The value is
// log10(2^(exponent bias)).
// The generic approximation uses the fact that log10(2^x) ~= x/3
-template <typename T> constexpr int32_t get_upper_bound() {
+template <typename T> LIBC_INLINE constexpr int32_t get_upper_bound() {
return fputil::FPBits<T>::EXP_BIAS / 3;
}
-template <> constexpr int32_t get_upper_bound<float>() { return 39; }
+template <> LIBC_INLINE constexpr int32_t get_upper_bound<float>() {
+ return 39;
+}
-template <> constexpr int32_t get_upper_bound<double>() { return 309; }
+template <> LIBC_INLINE constexpr int32_t get_upper_bound<double>() {
+ return 309;
+}
// The lower bound is the largest negative base-10 exponent that could possibly
// give a non-zero result for this size of float. The value is
@@ -614,18 +620,18 @@ template <> constexpr int32_t get_upper_bound<double>() { return 309; }
// low base 10 exponent with a very high intermediate mantissa can cancel each
// other out, and subnormal numbers allow for the result to be at the very low
// end of the final mantissa.
-template <typename T> constexpr int32_t get_lower_bound() {
+template <typename T> LIBC_INLINE constexpr int32_t get_lower_bound() {
using FPBits = typename fputil::FPBits<T>;
return -((FPBits::EXP_BIAS +
static_cast<int32_t>(FPBits::FRACTION_LEN + FPBits::STORAGE_LEN)) /
3);
}
-template <> constexpr int32_t get_lower_bound<float>() {
+template <> LIBC_INLINE constexpr int32_t get_lower_bound<float>() {
return -(39 + 6 + 10);
}
-template <> constexpr int32_t get_lower_bound<double>() {
+template <> LIBC_INLINE constexpr int32_t get_lower_bound<double>() {
return -(309 + 15 + 20);
}
@@ -635,9 +641,10 @@ template <> constexpr int32_t get_lower_bound<double>() {
// accuracy. The resulting mantissa and exponent are placed in outputMantissa
// and outputExp2.
template <class T>
-LIBC_INLINE FloatConvertReturn<T>
-decimal_exp_to_float(ExpandedFloat<T> init_num, const char *__restrict numStart,
- bool truncated, RoundDirection round) {
+LIBC_INLINE FloatConvertReturn<T> decimal_exp_to_float(
+ ExpandedFloat<T> init_num, bool truncated, RoundDirection round,
+ const char *__restrict numStart,
+ const size_t num_len = cpp::numeric_limits<size_t>::max()) {
using FPBits = typename fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
@@ -699,7 +706,7 @@ decimal_exp_to_float(ExpandedFloat<T> init_num, const char *__restrict numStart,
#endif // LIBC_COPT_STRTOFLOAT_DISABLE_EISEL_LEMIRE
#ifndef LIBC_COPT_STRTOFLOAT_DISABLE_SIMPLE_DECIMAL_CONVERSION
- output = simple_decimal_conversion<T>(numStart, round);
+ output = simple_decimal_conversion<T>(numStart, num_len, round);
#else
#warning "Simple decimal conversion is disabled, result may not be correct."
#endif // LIBC_COPT_STRTOFLOAT_DISABLE_SIMPLE_DECIMAL_CONVERSION
@@ -892,6 +899,8 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
if (!seen_digit)
return output;
+ // TODO: When adding max length argument, handle the case of a trailing
+ // EXPONENT MARKER, see scanf for more details.
if (tolower(src[index]) == EXPONENT_MARKER) {
bool has_sign = false;
if (src[index + 1] == '+' || src[index + 1] == '-') {
@@ -926,7 +935,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
output.value = {0, 0};
} else {
auto temp =
- decimal_exp_to_float<T>({mantissa, exponent}, src, truncated, round);
+ decimal_exp_to_float<T>({mantissa, exponent}, truncated, round, src);
output.value = temp.num;
output.error = temp.error;
}
@@ -1046,17 +1055,17 @@ hexadecimal_string_to_float(const char *__restrict src,
return output;
}
-LIBC_INLINE uint64_t
+template <class T>
+LIBC_INLINE typename fputil::FPBits<T>::StorageType
nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) {
- uint64_t nan_mantissa = 0;
+ using FPBits = typename fputil::FPBits<T>;
+ using StorageType = typename FPBits::StorageType;
+
+ StorageType nan_mantissa = 0;
if (ncharseq.data() != nullptr && isdigit(ncharseq[0])) {
- // This is to prevent errors when StorageType is larger than 64
- // bits, since strtointeger only supports up to 64 bits. This is
- // actually more than is required by the specification, which says
- // for the input type "NAN(n-char-sequence)" that "the meaning of
- // the n-char sequence is implementation-defined."
- auto strtoint_result = strtointeger<uint64_t>(ncharseq.data(), 0);
+ StrToNumResult<StorageType> strtoint_result =
+ strtointeger<StorageType>(ncharseq.data(), 0);
if (!strtoint_result.has_error())
nan_mantissa = strtoint_result.value;
@@ -1069,11 +1078,12 @@ nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) {
// Takes a pointer to a string and a pointer to a string pointer. This function
// is used as the backend for all of the string to float functions.
+// TODO: Add src_len member to match strtointeger.
+// TODO: Next, move from char* and length to string_view
template <class T>
LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
using FPBits = typename fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = fputil::Sign;
FPBits result = FPBits();
bool seen_digit = false;
@@ -1160,9 +1170,8 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
++index;
if (src[index] == ')') {
++index;
- auto nan_mantissa_result = nan_mantissa_from_ncharseq(
+ nan_mantissa = nan_mantissa_from_ncharseq<T>(
cpp::string_view(src + (left_paren + 1), index - left_paren - 2));
- nan_mantissa = static_cast<StorageType>(nan_mantissa_result);
} else {
index = left_paren;
}
@@ -1209,13 +1218,10 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
while (isalnum(arg[index]) || arg[index] == '_')
++index;
- if (arg[index] == '\0') {
- auto nan_mantissa_result =
- nan_mantissa_from_ncharseq(cpp::string_view(arg, index));
- nan_mantissa = static_cast<StorageType>(nan_mantissa_result);
- }
+ if (arg[index] == '\0')
+ nan_mantissa = nan_mantissa_from_ncharseq<T>(cpp::string_view(arg, index));
- result = FPBits::quiet_nan(fputil::Sign::POS, nan_mantissa);
+ result = FPBits::quiet_nan(Sign::POS, nan_mantissa);
return {result.get_val(), 0, error};
}
diff --git a/src/__support/str_to_integer.h b/src/__support/str_to_integer.h
index e83a508e086b..02c71d40a1c0 100644
--- a/src/__support/str_to_integer.h
+++ b/src/__support/str_to_integer.h
@@ -11,6 +11,7 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/UInt128.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/str_to_num_result.h"
@@ -21,11 +22,15 @@ namespace internal {
// Returns a pointer to the first character in src that is not a whitespace
// character (as determined by isspace())
-LIBC_INLINE const char *first_non_whitespace(const char *__restrict src) {
- while (internal::isspace(*src)) {
- ++src;
+// TODO: Change from returning a pointer to returning a length.
+LIBC_INLINE const char *
+first_non_whitespace(const char *__restrict src,
+ size_t src_len = cpp::numeric_limits<size_t>::max()) {
+ size_t src_cur = 0;
+ while (src_cur < src_len && internal::isspace(src[src_cur])) {
+ ++src_cur;
}
- return src;
+ return src + src_cur;
}
LIBC_INLINE int b36_char_to_int(char input) {
@@ -38,78 +43,86 @@ LIBC_INLINE int b36_char_to_int(char input) {
// checks if the next 3 characters of the string pointer are the start of a
// hexadecimal number. Does not advance the string pointer.
-LIBC_INLINE bool is_hex_start(const char *__restrict src) {
+LIBC_INLINE bool
+is_hex_start(const char *__restrict src,
+ size_t src_len = cpp::numeric_limits<size_t>::max()) {
+ if (src_len < 3)
+ return false;
return *src == '0' && (*(src + 1) | 32) == 'x' && isalnum(*(src + 2)) &&
b36_char_to_int(*(src + 2)) < 16;
}
// Takes the address of the string pointer and parses the base from the start of
-// it. This function will advance |src| to the first valid digit in the inferred
-// base.
-LIBC_INLINE int infer_base(const char *__restrict *__restrict src) {
+// it.
+LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) {
// A hexadecimal number is defined as "the prefix 0x or 0X followed by a
// sequence of the decimal digits and the letters a (or A) through f (or F)
// with values 10 through 15 respectively." (C standard 6.4.4.1)
- if (is_hex_start(*src)) {
- (*src) += 2;
+ if (is_hex_start(src, src_len))
return 16;
- } // An octal number is defined as "the prefix 0 optionally followed by a
- // sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any
- // number that starts with 0, including just 0, is an octal number.
- else if (**src == '0') {
+ // An octal number is defined as "the prefix 0 optionally followed by a
+ // sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any
+ // number that starts with 0, including just 0, is an octal number.
+ if (src_len > 0 && src[0] == '0')
return 8;
- } // A decimal number is defined as beginning "with a nonzero digit and
- // consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1)
- else {
- return 10;
- }
+ // A decimal number is defined as beginning "with a nonzero digit and
+ // consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1)
+ return 10;
}
// Takes a pointer to a string and the base to convert to. This function is used
// as the backend for all of the string to int functions.
template <class T>
-LIBC_INLINE StrToNumResult<T> strtointeger(const char *__restrict src,
- int base) {
- unsigned long long result = 0;
+LIBC_INLINE StrToNumResult<T>
+strtointeger(const char *__restrict src, int base,
+ const size_t src_len = cpp::numeric_limits<size_t>::max()) {
+ using ResultType = typename cpp::conditional_t<(cpp::is_same_v<T, UInt128> ||
+ cpp::is_same_v<T, Int128>),
+ UInt128, unsigned long long>;
+
+ ResultType result = 0;
+
bool is_number = false;
- const char *original_src = src;
+ size_t src_cur = 0;
int error_val = 0;
- if (base < 0 || base == 1 || base > 36) {
- error_val = EINVAL;
- return {0, 0, error_val};
- }
+ if (src_len == 0)
+ return {0, 0, 0};
+
+ if (base < 0 || base == 1 || base > 36)
+ return {0, 0, EINVAL};
- src = first_non_whitespace(src);
+ src_cur = first_non_whitespace(src, src_len) - src;
char result_sign = '+';
- if (*src == '+' || *src == '-') {
- result_sign = *src;
- ++src;
+ if (src[src_cur] == '+' || src[src_cur] == '-') {
+ result_sign = src[src_cur];
+ ++src_cur;
}
- if (base == 0) {
- base = infer_base(&src);
- } else if (base == 16 && is_hex_start(src)) {
- src = src + 2;
- }
+ if (base == 0)
+ base = infer_base(src + src_cur, src_len - src_cur);
+
+ if (base == 16 && is_hex_start(src + src_cur, src_len - src_cur))
+ src_cur = src_cur + 2;
- constexpr bool IS_UNSIGNED = (cpp::numeric_limits<T>::min() == 0);
+ constexpr bool IS_UNSIGNED = cpp::is_unsigned_v<T>;
const bool is_positive = (result_sign == '+');
- unsigned long long constexpr NEGATIVE_MAX =
- !IS_UNSIGNED
- ? static_cast<unsigned long long>(cpp::numeric_limits<T>::max()) + 1
- : cpp::numeric_limits<T>::max();
- unsigned long long const abs_max =
+
+ ResultType constexpr NEGATIVE_MAX =
+ !IS_UNSIGNED ? static_cast<ResultType>(cpp::numeric_limits<T>::max()) + 1
+ : cpp::numeric_limits<T>::max();
+ ResultType const abs_max =
(is_positive ? cpp::numeric_limits<T>::max() : NEGATIVE_MAX);
- unsigned long long const abs_max_div_by_base = abs_max / base;
- while (isalnum(*src)) {
- int cur_digit = b36_char_to_int(*src);
+ ResultType const abs_max_div_by_base = abs_max / base;
+
+ while (src_cur < src_len && isalnum(src[src_cur])) {
+ int cur_digit = b36_char_to_int(src[src_cur]);
if (cur_digit >= base)
break;
is_number = true;
- ++src;
+ ++src_cur;
// If the number has already hit the maximum value for the current type then
// the result cannot change, but we still need to advance src to the end of
@@ -133,7 +146,7 @@ LIBC_INLINE StrToNumResult<T> strtointeger(const char *__restrict src,
}
}
- ptrdiff_t str_len = is_number ? (src - original_src) : 0;
+ ptrdiff_t str_len = is_number ? (src_cur) : 0;
if (error_val == ERANGE) {
if (is_positive || IS_UNSIGNED)
@@ -142,10 +155,12 @@ LIBC_INLINE StrToNumResult<T> strtointeger(const char *__restrict src,
return {cpp::numeric_limits<T>::min(), str_len, error_val};
}
- return {is_positive
- ? static_cast<T>(result)
- : static_cast<T>(-static_cast<cpp::make_unsigned_t<T>>(result)),
- str_len, error_val};
+ return {
+ is_positive
+ ? static_cast<T>(result)
+ : static_cast<T>(
+ -static_cast<make_integral_or_big_int_unsigned_t<T>>(result)),
+ str_len, error_val};
}
} // namespace internal
diff --git a/src/__support/threads/gpu/mutex.h b/src/__support/threads/gpu/mutex.h
index 7a23604b5b98..71d0ef04cbfe 100644
--- a/src/__support/threads/gpu/mutex.h
+++ b/src/__support/threads/gpu/mutex.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_THREAD_GPU_MUTEX_H
-#define LLVM_LIBC_SRC___SUPPORT_THREAD_GPU_MUTEX_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
#include "src/__support/macros/attributes.h"
#include "src/__support/threads/mutex_common.h"
@@ -28,4 +28,4 @@ struct Mutex {
} // namespace LIBC_NAMESPACE
-#endif
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
diff --git a/src/__support/threads/sleep.h b/src/__support/threads/sleep.h
new file mode 100644
index 000000000000..9a2dff598ece
--- /dev/null
+++ b/src/__support/threads/sleep.h
@@ -0,0 +1,34 @@
+//===-- Utilities for suspending threads ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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_THREADS_SLEEP_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_SLEEP_H
+
+#include "src/__support/macros/attributes.h"
+
+namespace LIBC_NAMESPACE {
+
+/// Suspend the thread briefly to assist the thread scheduler during busy loops.
+LIBC_INLINE void sleep_briefly() {
+#if defined(LIBC_TARGET_ARCH_IS_NVPTX)
+ if (__nvvm_reflect("__CUDA_ARCH") >= 700)
+ LIBC_INLINE_ASM("nanosleep.u32 64;" ::: "memory");
+#elif defined(LIBC_TARGET_ARCH_IS_AMDGPU)
+ __builtin_amdgcn_s_sleep(2);
+#elif defined(LIBC_TARGET_ARCH_IS_X86)
+ __builtin_ia32_pause();
+#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)
+ __builtin_arm_isb(0xf);
+#else
+ // Simply do nothing if sleeping isn't supported on this platform.
+#endif
+}
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_SLEEP_H
diff --git a/src/assert/assert.h b/src/assert/assert.h
index 0318a934acca..6f352af1988b 100644
--- a/src/assert/assert.h
+++ b/src/assert/assert.h
@@ -1,3 +1,4 @@
+// NOLINT(llvm-header-guard) https://github.com/llvm/llvm-project/issues/83339
//===-- Internal header for assert ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -21,4 +22,4 @@
((e) ? (void)0 \
: LIBC_NAMESPACE::__assert_fail(#e, __FILE__, __LINE__, \
__PRETTY_FUNCTION__))
-#endif
+#endif // NDEBUG
diff --git a/src/errno/libc_errno.cpp b/src/errno/libc_errno.cpp
index c8f0bffd0962..30b0a67a3241 100644
--- a/src/errno/libc_errno.cpp
+++ b/src/errno/libc_errno.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of errno -------------------------------------------===//
+//===-- Implementation of libc_errno --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,35 +6,45 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/properties/architectures.h"
-
-namespace LIBC_NAMESPACE {
+#include "libc_errno.h"
#ifdef LIBC_TARGET_ARCH_IS_GPU
-struct ErrnoConsumer {
- void operator=(int) {}
-};
-#endif
+// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just
+// a global errno for gpu to use for now.
+extern "C" {
+LIBC_THREAD_LOCAL int __llvmlibc_gpu_errno;
+}
+
+void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_gpu_errno = a; }
+LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_gpu_errno; }
+#elif !defined(LIBC_COPT_PUBLIC_PACKAGING)
+// This mode is for unit testing. We just use our internal errno.
+LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
+
+void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_internal_errno = a; }
+LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_internal_errno; }
+
+#elif defined(LIBC_FULL_BUILD)
+// This mode is for public libc archive, hermetic, and integration tests.
+// In full build mode, we provide the errno storage ourselves.
extern "C" {
-#ifdef LIBC_COPT_PUBLIC_PACKAGING
-// TODO: Declare __llvmlibc_errno only under LIBC_COPT_PUBLIC_PACKAGING and
-// __llvmlibc_internal_errno otherwise.
-// In overlay mode, this will be an unused thread local variable as libc_errno
-// will resolve to errno from the system libc's errno.h. In full build mode
-// however, libc_errno will resolve to this thread local variable via the errno
-// macro defined in LLVM libc's public errno.h header file.
-// TODO: Use a macro to distinguish full build and overlay build which can be
-// used to exclude __llvmlibc_errno under overlay build.
-#ifdef LIBC_TARGET_ARCH_IS_GPU
-ErrnoConsumer __llvmlibc_errno;
-#else
LIBC_THREAD_LOCAL int __llvmlibc_errno;
-#endif // LIBC_TARGET_ARCH_IS_GPU
+}
+
+void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_errno = a; }
+LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_errno; }
+
#else
-LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
-#endif
-} // extern "C"
+// In overlay mode, we simply use the system errno.
+#include <errno.h>
+void LIBC_NAMESPACE::Errno::operator=(int a) { errno = a; }
+LIBC_NAMESPACE::Errno::operator int() { return errno; }
+
+#endif // LIBC_FULL_BUILD
+
+namespace LIBC_NAMESPACE {
+// Define the global `libc_errno` instance.
+Errno libc_errno;
} // namespace LIBC_NAMESPACE
diff --git a/src/errno/libc_errno.h b/src/errno/libc_errno.h
index fbcd1c3395cd..5afc0a41d348 100644
--- a/src/errno/libc_errno.h
+++ b/src/errno/libc_errno.h
@@ -1,4 +1,4 @@
-//===-- Implementation header for errno -------------------------*- C++ -*-===//
+//===-- Implementation header for libc_errno --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -12,45 +12,36 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/properties/architectures.h"
+// TODO: https://github.com/llvm/llvm-project/issues/80172
+// Separate just the definition of errno numbers in
+// include/llvm-libc-macros/* and only include that instead of the system
+// <errno.h>.
#include <errno.h>
-// If we are targeting the GPU we currently don't support 'errno'. We simply
-// consume it.
-#ifdef LIBC_TARGET_ARCH_IS_GPU
+// This header is to be consumed by internal implementations, in which all of
+// them should refer to `libc_errno` instead of using `errno` directly from
+// <errno.h> header.
+
+// Unit and hermetic tests should:
+// - #include "src/errno/libc_errno.h"
+// - NOT #include <errno.h>
+// - Only use `libc_errno` in the code
+// - Depend on libc.src.errno.errno
+
+// Integration tests should:
+// - NOT #include "src/errno/libc_errno.h"
+// - #include <errno.h>
+// - Use regular `errno` in the code
+// - Still depend on libc.src.errno.errno
+
namespace LIBC_NAMESPACE {
-struct ErrnoConsumer {
- void operator=(int) {}
+struct Errno {
+ void operator=(int);
+ operator int();
};
-} // namespace LIBC_NAMESPACE
-#endif
-
-// All of the libc runtime and test code should use the "libc_errno" macro. They
-// should not refer to the "errno" macro directly.
-#ifdef LIBC_COPT_PUBLIC_PACKAGING
-#ifdef LIBC_TARGET_ARCH_IS_GPU
-extern "C" LIBC_NAMESPACE::ErrnoConsumer __llvmlibc_errno;
-#define libc_errno __llvmlibc_errno
-#else
-// This macro will resolve to errno from the errno.h file included above. Under
-// full build, this will be LLVM libc's errno. In overlay build, it will be
-// system libc's errno.
-#define libc_errno errno
-#endif
-#else
-namespace LIBC_NAMESPACE {
-
-// TODO: On the GPU build this will be mapped to a single global value. We need
-// to ensure that tests are not run with multiple threads that depend on errno
-// until we have true 'thread_local' support on the GPU.
-extern "C" LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
-// TODO: After all of libc/src and libc/test are switched over to use
-// libc_errno, this header file will be "shipped" via an add_entrypoint_object
-// target. At which point libc_errno, should point to __llvmlibc_internal_errno
-// if LIBC_COPT_PUBLIC_PACKAGING is not defined.
-#define libc_errno LIBC_NAMESPACE::__llvmlibc_internal_errno
+extern Errno libc_errno;
} // namespace LIBC_NAMESPACE
-#endif
#endif // LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H
diff --git a/src/gpu/rpc_fprintf.cpp b/src/gpu/rpc_fprintf.cpp
new file mode 100644
index 000000000000..7b0e60b59baf
--- /dev/null
+++ b/src/gpu/rpc_fprintf.cpp
@@ -0,0 +1,71 @@
+//===-- GPU implementation of fprintf -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "rpc_fprintf.h"
+
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/GPU/utils.h"
+#include "src/__support/RPC/rpc_client.h"
+#include "src/__support/common.h"
+#include "src/stdio/gpu/file.h"
+
+namespace LIBC_NAMESPACE {
+
+template <uint16_t opcode>
+int fprintf_impl(::FILE *__restrict file, const char *__restrict format,
+ size_t format_size, void *args, size_t args_size) {
+ uint64_t mask = gpu::get_lane_mask();
+ rpc::Client::Port port = rpc::client.open<opcode>();
+
+ if constexpr (opcode == RPC_PRINTF_TO_STREAM) {
+ port.send([&](rpc::Buffer *buffer) {
+ buffer->data[0] = reinterpret_cast<uintptr_t>(file);
+ });
+ }
+
+ port.send_n(format, format_size);
+ port.send_n(args, args_size);
+
+ uint32_t ret = 0;
+ for (;;) {
+ const char *str = nullptr;
+ port.recv([&](rpc::Buffer *buffer) {
+ ret = static_cast<uint32_t>(buffer->data[0]);
+ str = reinterpret_cast<const char *>(buffer->data[1]);
+ });
+ // If any lanes have a string argument it needs to be copied back.
+ if (!gpu::ballot(mask, str))
+ break;
+
+ uint64_t size = str ? internal::string_length(str) + 1 : 0;
+ port.send_n(str, size);
+ }
+
+ port.close();
+ return ret;
+}
+
+// TODO: This is a stand-in function that uses a struct pointer and size in
+// place of varargs. Once varargs support is added we will use that to
+// implement the real version.
+LLVM_LIBC_FUNCTION(int, rpc_fprintf,
+ (::FILE *__restrict stream, const char *__restrict format,
+ void *args, size_t size)) {
+ cpp::string_view str(format);
+ if (stream == stdout)
+ return fprintf_impl<RPC_PRINTF_TO_STDOUT>(stream, format, str.size() + 1,
+ args, size);
+ else if (stream == stderr)
+ return fprintf_impl<RPC_PRINTF_TO_STDERR>(stream, format, str.size() + 1,
+ args, size);
+ else
+ return fprintf_impl<RPC_PRINTF_TO_STREAM>(stream, format, str.size() + 1,
+ args, size);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/gpu/rpc_fprintf.h b/src/gpu/rpc_fprintf.h
new file mode 100644
index 000000000000..053f7b4f818a
--- /dev/null
+++ b/src/gpu/rpc_fprintf.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for RPC functions -----------------*- 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_GPU_RPC_HOST_CALL_H
+#define LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H
+
+#include <stddef.h>
+#include <stdio.h>
+
+namespace LIBC_NAMESPACE {
+
+int rpc_fprintf(::FILE *__restrict stream, const char *__restrict format,
+ void *argc, size_t size);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H
diff --git a/src/gpu/rpc_host_call.h b/src/gpu/rpc_host_call.h
index 14393ab95dc1..473d90ba48fd 100644
--- a/src/gpu/rpc_host_call.h
+++ b/src/gpu/rpc_host_call.h
@@ -17,4 +17,4 @@ void rpc_host_call(void *fn, void *buffer, size_t size);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_GPU_RPC_H_HOST_CALL
+#endif // LLVM_LIBC_SRC_GPU_RPC_HOST_CALL_H
diff --git a/src/math/amdgpu/acos.cpp b/src/math/amdgpu/acos.cpp
new file mode 100644
index 000000000000..b1e30fef82de
--- /dev/null
+++ b/src/math/amdgpu/acos.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU acos 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/acos.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, acos, (double x)) { return __ocml_acos_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/acosf.cpp b/src/math/amdgpu/acosf.cpp
new file mode 100644
index 000000000000..4c2dd4bcf435
--- /dev/null
+++ b/src/math/amdgpu/acosf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the acosf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/acosf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return __ocml_acos_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/acosh.cpp b/src/math/amdgpu/acosh.cpp
new file mode 100644
index 000000000000..dcdeeab29454
--- /dev/null
+++ b/src/math/amdgpu/acosh.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU acosh 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/acosh.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, acosh, (double x)) { return __ocml_acosh_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/acoshf.cpp b/src/math/amdgpu/acoshf.cpp
new file mode 100644
index 000000000000..52baa2eaecc7
--- /dev/null
+++ b/src/math/amdgpu/acoshf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the acoshf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/acoshf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return __ocml_acosh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/asin.cpp b/src/math/amdgpu/asin.cpp
new file mode 100644
index 000000000000..835c317112e2
--- /dev/null
+++ b/src/math/amdgpu/asin.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU asin 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/asin.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, asin, (double x)) { return __ocml_asin_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/asinf.cpp b/src/math/amdgpu/asinf.cpp
new file mode 100644
index 000000000000..72c45d5cf172
--- /dev/null
+++ b/src/math/amdgpu/asinf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the asinf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/asinf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, asinf, (float x)) { return __ocml_asin_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/asinh.cpp b/src/math/amdgpu/asinh.cpp
new file mode 100644
index 000000000000..7a9f7ea4e988
--- /dev/null
+++ b/src/math/amdgpu/asinh.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU asinh 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/asinh.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, asinh, (double x)) { return __ocml_asinh_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/asinhf.cpp b/src/math/amdgpu/asinhf.cpp
new file mode 100644
index 000000000000..28d6bde5c918
--- /dev/null
+++ b/src/math/amdgpu/asinhf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the asinhf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/asinhf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { return __ocml_asinh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atan.cpp b/src/math/amdgpu/atan.cpp
new file mode 100644
index 000000000000..a1fa38ba451d
--- /dev/null
+++ b/src/math/amdgpu/atan.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU atan 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/atan.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, atan, (double x)) { return __ocml_atan_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atan2.cpp b/src/math/amdgpu/atan2.cpp
new file mode 100644
index 000000000000..9cfdba75eb8d
--- /dev/null
+++ b/src/math/amdgpu/atan2.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the GPU atan2 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/atan2.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, atan2, (double x, double y)) {
+ return __ocml_atan2_f64(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atan2f.cpp b/src/math/amdgpu/atan2f.cpp
new file mode 100644
index 000000000000..ef56293b4caf
--- /dev/null
+++ b/src/math/amdgpu/atan2f.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the GPU atan2f 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/atan2f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, atan2f, (float x, float y)) {
+ return __ocml_atan2_f32(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atanf.cpp b/src/math/amdgpu/atanf.cpp
new file mode 100644
index 000000000000..bbcceca3ed09
--- /dev/null
+++ b/src/math/amdgpu/atanf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the atanf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/atanf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, atanf, (float x)) { return __ocml_atan_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atanh.cpp b/src/math/amdgpu/atanh.cpp
new file mode 100644
index 000000000000..ec462586450b
--- /dev/null
+++ b/src/math/amdgpu/atanh.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU atanh 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/atanh.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, atanh, (double x)) { return __ocml_atanh_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/atanhf.cpp b/src/math/amdgpu/atanhf.cpp
new file mode 100644
index 000000000000..227269369ab6
--- /dev/null
+++ b/src/math/amdgpu/atanhf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the atanhf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/atanhf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { return __ocml_atanh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/ceil.cpp b/src/math/amdgpu/ceil.cpp
index ad1407d61f62..ad1407d61f62 100644
--- a/src/math/gpu/ceil.cpp
+++ b/src/math/amdgpu/ceil.cpp
diff --git a/src/math/gpu/ceilf.cpp b/src/math/amdgpu/ceilf.cpp
index c4fc58d93603..c4fc58d93603 100644
--- a/src/math/gpu/ceilf.cpp
+++ b/src/math/amdgpu/ceilf.cpp
diff --git a/src/math/gpu/copysign.cpp b/src/math/amdgpu/copysign.cpp
index 6f804bdb90a1..6f804bdb90a1 100644
--- a/src/math/gpu/copysign.cpp
+++ b/src/math/amdgpu/copysign.cpp
diff --git a/src/math/gpu/copysignf.cpp b/src/math/amdgpu/copysignf.cpp
index 4d7e132462ac..4d7e132462ac 100644
--- a/src/math/gpu/copysignf.cpp
+++ b/src/math/amdgpu/copysignf.cpp
diff --git a/src/math/amdgpu/cos.cpp b/src/math/amdgpu/cos.cpp
new file mode 100644
index 000000000000..68239d933780
--- /dev/null
+++ b/src/math/amdgpu/cos.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the cos function for GPU ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/cos.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, cos, (double x)) { return __ocml_cos_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/cosf.cpp b/src/math/amdgpu/cosf.cpp
new file mode 100644
index 000000000000..a60e9ea28907
--- /dev/null
+++ b/src/math/amdgpu/cosf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the cosf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/cosf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return __ocml_cos_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/cosh.cpp b/src/math/amdgpu/cosh.cpp
new file mode 100644
index 000000000000..b71df0c0170c
--- /dev/null
+++ b/src/math/amdgpu/cosh.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the cosh function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/cosh.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, cosh, (double x)) { return __ocml_cosh_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/coshf.cpp b/src/math/amdgpu/coshf.cpp
new file mode 100644
index 000000000000..699fb0478aee
--- /dev/null
+++ b/src/math/amdgpu/coshf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the coshf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/coshf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return __ocml_cosh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/amdgpu/declarations.h b/src/math/amdgpu/declarations.h
index 7a01cbc6ab19..5d7f3c9609d2 100644
--- a/src/math/gpu/vendor/amdgpu/declarations.h
+++ b/src/math/amdgpu/declarations.h
@@ -6,8 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GPU_AMDGPU_DECLARATIONS_H
-#define LLVM_LIBC_SRC_MATH_GPU_AMDGPU_DECLARATIONS_H
+#ifndef LLVM_LIBC_SRC_MATH_AMDGPU_DECLARATIONS_H
+#define LLVM_LIBC_SRC_MATH_AMDGPU_DECLARATIONS_H
+
+#include "platform.h"
#include "src/__support/GPU/utils.h"
@@ -81,4 +83,4 @@ float __ocml_tgamma_f32(float);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_MATH_GPU_AMDGPU_DECLARATIONS_H
+#endif // LLVM_LIBC_SRC_MATH_AMDGPU_DECLARATIONS_H
diff --git a/src/math/amdgpu/erf.cpp b/src/math/amdgpu/erf.cpp
new file mode 100644
index 000000000000..7a464550c7e0
--- /dev/null
+++ b/src/math/amdgpu/erf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU erf 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/erf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, erf, (double x)) { return __ocml_erf_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/erff.cpp b/src/math/amdgpu/erff.cpp
new file mode 100644
index 000000000000..1f77d08585a3
--- /dev/null
+++ b/src/math/amdgpu/erff.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU erff 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/erff.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, erff, (float x)) { return __ocml_erf_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/exp.cpp b/src/math/amdgpu/exp.cpp
new file mode 100644
index 000000000000..d19c73dd0242
--- /dev/null
+++ b/src/math/amdgpu/exp.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU exp 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/exp.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, exp, (double x)) { return __ocml_exp_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/exp10.cpp b/src/math/amdgpu/exp10.cpp
new file mode 100644
index 000000000000..17d8f3350ac2
--- /dev/null
+++ b/src/math/amdgpu/exp10.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU exp10 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/exp10.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, exp10, (double x)) { return __ocml_exp10_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/exp10f.cpp b/src/math/amdgpu/exp10f.cpp
new file mode 100644
index 000000000000..ddab555a8fbd
--- /dev/null
+++ b/src/math/amdgpu/exp10f.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the exp10f function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/exp10f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { return __ocml_exp10_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/exp2.cpp b/src/math/amdgpu/exp2.cpp
new file mode 100644
index 000000000000..dfbb1f80d129
--- /dev/null
+++ b/src/math/amdgpu/exp2.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU exp2 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/exp2.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, exp2, (double x)) { return __ocml_exp2_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/exp2f.cpp b/src/math/amdgpu/exp2f.cpp
new file mode 100644
index 000000000000..016dfe3a6222
--- /dev/null
+++ b/src/math/amdgpu/exp2f.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the exp2f function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/exp2f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { return __ocml_exp2_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/expf.cpp b/src/math/amdgpu/expf.cpp
new file mode 100644
index 000000000000..33393078cfa3
--- /dev/null
+++ b/src/math/amdgpu/expf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the expf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/expf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, expf, (float x)) { return __ocml_exp_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/expm1.cpp b/src/math/amdgpu/expm1.cpp
new file mode 100644
index 000000000000..d2ac28ae6a3e
--- /dev/null
+++ b/src/math/amdgpu/expm1.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU expm1 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/expm1.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, expm1, (double x)) { return __ocml_expm1_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/expm1f.cpp b/src/math/amdgpu/expm1f.cpp
new file mode 100644
index 000000000000..0ffe1a362af1
--- /dev/null
+++ b/src/math/amdgpu/expm1f.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the expm1f function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/expm1f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { return __ocml_expm1_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/fabs.cpp b/src/math/amdgpu/fabs.cpp
index c0d063d50ae5..c0d063d50ae5 100644
--- a/src/math/gpu/fabs.cpp
+++ b/src/math/amdgpu/fabs.cpp
diff --git a/src/math/gpu/fabsf.cpp b/src/math/amdgpu/fabsf.cpp
index 398ffd0c74c0..398ffd0c74c0 100644
--- a/src/math/gpu/fabsf.cpp
+++ b/src/math/amdgpu/fabsf.cpp
diff --git a/src/math/amdgpu/fdim.cpp b/src/math/amdgpu/fdim.cpp
new file mode 100644
index 000000000000..f16942dc6193
--- /dev/null
+++ b/src/math/amdgpu/fdim.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the fdim function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fdim.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fdim, (double x, double y)) {
+ return __ocml_fdim_f64(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/fdimf.cpp b/src/math/amdgpu/fdimf.cpp
new file mode 100644
index 000000000000..eccb441f1455
--- /dev/null
+++ b/src/math/amdgpu/fdimf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the fdimf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fdimf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fdimf, (float x, float y)) {
+ return __ocml_fdim_f32(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/floor.cpp b/src/math/amdgpu/floor.cpp
index eada89c178d7..eada89c178d7 100644
--- a/src/math/gpu/floor.cpp
+++ b/src/math/amdgpu/floor.cpp
diff --git a/src/math/gpu/floorf.cpp b/src/math/amdgpu/floorf.cpp
index a5611c515a88..a5611c515a88 100644
--- a/src/math/gpu/floorf.cpp
+++ b/src/math/amdgpu/floorf.cpp
diff --git a/src/math/gpu/fma.cpp b/src/math/amdgpu/fma.cpp
index 41a6ddf60dbc..41a6ddf60dbc 100644
--- a/src/math/gpu/fma.cpp
+++ b/src/math/amdgpu/fma.cpp
diff --git a/src/math/gpu/fmaf.cpp b/src/math/amdgpu/fmaf.cpp
index c948e32f77eb..c948e32f77eb 100644
--- a/src/math/gpu/fmaf.cpp
+++ b/src/math/amdgpu/fmaf.cpp
diff --git a/src/math/amdgpu/fmax.cpp b/src/math/amdgpu/fmax.cpp
new file mode 100644
index 000000000000..09f0f942a042
--- /dev/null
+++ b/src/math/amdgpu/fmax.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmax function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmax.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
+ return __builtin_fmax(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/fmaxf.cpp b/src/math/amdgpu/fmaxf.cpp
index 67178b3e2735..5913a85df637 100644
--- a/src/math/gpu/fmaxf.cpp
+++ b/src/math/amdgpu/fmaxf.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/math/fmaxf.h"
+
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/gpu/fmin.cpp b/src/math/amdgpu/fmin.cpp
index 7303adcd347e..0d6f3521dcb7 100644
--- a/src/math/gpu/fmin.cpp
+++ b/src/math/amdgpu/fmin.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/math/fmin.h"
+
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/gpu/fminf.cpp b/src/math/amdgpu/fminf.cpp
index bbf0c677b5e3..42744abfb3b0 100644
--- a/src/math/gpu/fminf.cpp
+++ b/src/math/amdgpu/fminf.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/math/fminf.h"
+
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/gpu/fmod.cpp b/src/math/amdgpu/fmod.cpp
index 0654cdd2abe0..0654cdd2abe0 100644
--- a/src/math/gpu/fmod.cpp
+++ b/src/math/amdgpu/fmod.cpp
diff --git a/src/math/gpu/fmodf.cpp b/src/math/amdgpu/fmodf.cpp
index b689046468fb..b689046468fb 100644
--- a/src/math/gpu/fmodf.cpp
+++ b/src/math/amdgpu/fmodf.cpp
diff --git a/src/math/amdgpu/frexp.cpp b/src/math/amdgpu/frexp.cpp
new file mode 100644
index 000000000000..0acf97342fa0
--- /dev/null
+++ b/src/math/amdgpu/frexp.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the frexp function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/frexp.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, frexp, (double x, int *p)) {
+ return __builtin_frexp(x, p);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/frexpf.cpp b/src/math/amdgpu/frexpf.cpp
new file mode 100644
index 000000000000..d870bf3095b2
--- /dev/null
+++ b/src/math/amdgpu/frexpf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the frexpf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/frexpf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, frexpf, (float x, int *p)) {
+ return __builtin_frexpf(x, p);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/hypot.cpp b/src/math/amdgpu/hypot.cpp
new file mode 100644
index 000000000000..ffc13504c8f4
--- /dev/null
+++ b/src/math/amdgpu/hypot.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the hypot function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/hypot.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, hypot, (double x, double y)) {
+ return __ocml_hypot_f64(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/hypotf.cpp b/src/math/amdgpu/hypotf.cpp
new file mode 100644
index 000000000000..811fc540488d
--- /dev/null
+++ b/src/math/amdgpu/hypotf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the hypotf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/hypotf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
+ return __ocml_hypot_f32(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/ilogb.cpp b/src/math/amdgpu/ilogb.cpp
new file mode 100644
index 000000000000..4479908d3856
--- /dev/null
+++ b/src/math/amdgpu/ilogb.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the ilogb function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ilogb.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return __ocml_ilogb_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/ilogbf.cpp b/src/math/amdgpu/ilogbf.cpp
new file mode 100644
index 000000000000..cded285c72f3
--- /dev/null
+++ b/src/math/amdgpu/ilogbf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the ilogbf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ilogbf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return __ocml_ilogb_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/ldexp.cpp b/src/math/amdgpu/ldexp.cpp
new file mode 100644
index 000000000000..70c5b0d6e555
--- /dev/null
+++ b/src/math/amdgpu/ldexp.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the ldexp function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ldexp.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, ldexp, (double x, int y)) {
+ return __builtin_ldexp(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/ldexpf.cpp b/src/math/amdgpu/ldexpf.cpp
new file mode 100644
index 000000000000..8dc7c132ee21
--- /dev/null
+++ b/src/math/amdgpu/ldexpf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the ldexpf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ldexpf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, ldexpf, (float x, int y)) {
+ return __builtin_ldexpf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/llrint.cpp b/src/math/amdgpu/llrint.cpp
index aafd1609002b..307420a9b8b2 100644
--- a/src/math/gpu/vendor/llrint.cpp
+++ b/src/math/amdgpu/llrint.cpp
@@ -9,12 +9,12 @@
#include "src/math/llrint.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(long long, llrint, (double x)) {
- return internal::llrint(x);
+ return static_cast<long long>(__builtin_rint(x));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/llrintf.cpp b/src/math/amdgpu/llrintf.cpp
index 39cd3ad0c021..23404990fb1b 100644
--- a/src/math/gpu/vendor/llrintf.cpp
+++ b/src/math/amdgpu/llrintf.cpp
@@ -9,12 +9,12 @@
#include "src/math/llrintf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(long long, llrintf, (float x)) {
- return internal::llrintf(x);
+ return static_cast<long long>(__builtin_rintf(x));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log.cpp b/src/math/amdgpu/log.cpp
new file mode 100644
index 000000000000..3f2489580356
--- /dev/null
+++ b/src/math/amdgpu/log.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log 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/log.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, log, (double x)) { return __ocml_log_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log10.cpp b/src/math/amdgpu/log10.cpp
new file mode 100644
index 000000000000..d522d5e84291
--- /dev/null
+++ b/src/math/amdgpu/log10.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log10 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/log10.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, log10, (double x)) { return __ocml_log10_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log10f.cpp b/src/math/amdgpu/log10f.cpp
new file mode 100644
index 000000000000..47b9b162ad9d
--- /dev/null
+++ b/src/math/amdgpu/log10f.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log10f 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/log10f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, log10f, (float x)) { return __ocml_log10_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log1p.cpp b/src/math/amdgpu/log1p.cpp
new file mode 100644
index 000000000000..fae60e448586
--- /dev/null
+++ b/src/math/amdgpu/log1p.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log1p 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/log1p.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, log1p, (double x)) { return __ocml_log1p_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log1pf.cpp b/src/math/amdgpu/log1pf.cpp
new file mode 100644
index 000000000000..e7b1772158fc
--- /dev/null
+++ b/src/math/amdgpu/log1pf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log1pf 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/log1pf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { return __ocml_log1p_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log2.cpp b/src/math/amdgpu/log2.cpp
new file mode 100644
index 000000000000..9d84f62dff6f
--- /dev/null
+++ b/src/math/amdgpu/log2.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log2 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/log2.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, log2, (double x)) { return __ocml_log2_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/log2f.cpp b/src/math/amdgpu/log2f.cpp
new file mode 100644
index 000000000000..7742a6141c37
--- /dev/null
+++ b/src/math/amdgpu/log2f.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU log2f 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/log2f.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, log2f, (float x)) { return __ocml_log2_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/logb.cpp b/src/math/amdgpu/logb.cpp
new file mode 100644
index 000000000000..1344fbb182af
--- /dev/null
+++ b/src/math/amdgpu/logb.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU logb 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/logb.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, logb, (double x)) { return __ocml_logb_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/logbf.cpp b/src/math/amdgpu/logbf.cpp
new file mode 100644
index 000000000000..fdb493fe28da
--- /dev/null
+++ b/src/math/amdgpu/logbf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU logbf 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/logbf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return __ocml_logb_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/logf.cpp b/src/math/amdgpu/logf.cpp
new file mode 100644
index 000000000000..d4d4b265ee5c
--- /dev/null
+++ b/src/math/amdgpu/logf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU logf 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/logf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, logf, (float x)) { return __ocml_log_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/lrint.cpp b/src/math/amdgpu/lrint.cpp
new file mode 100644
index 000000000000..b335b4f06393
--- /dev/null
+++ b/src/math/amdgpu/lrint.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the lrint function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/lrint.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, lrint, (double x)) {
+ return static_cast<long>(__builtin_rint(x));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/lrintf.cpp b/src/math/amdgpu/lrintf.cpp
new file mode 100644
index 000000000000..7959e76728a4
--- /dev/null
+++ b/src/math/amdgpu/lrintf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the lrintf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/lrintf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, lrintf, (float x)) {
+ return static_cast<long>(__builtin_rintf(x));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/nearbyint.cpp b/src/math/amdgpu/nearbyint.cpp
index 9c7b600df708..9c7b600df708 100644
--- a/src/math/gpu/nearbyint.cpp
+++ b/src/math/amdgpu/nearbyint.cpp
diff --git a/src/math/gpu/nearbyintf.cpp b/src/math/amdgpu/nearbyintf.cpp
index 7fbe9f4f0e0b..7fbe9f4f0e0b 100644
--- a/src/math/gpu/nearbyintf.cpp
+++ b/src/math/amdgpu/nearbyintf.cpp
diff --git a/src/math/amdgpu/nextafter.cpp b/src/math/amdgpu/nextafter.cpp
new file mode 100644
index 000000000000..5c74ef165268
--- /dev/null
+++ b/src/math/amdgpu/nextafter.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the nextafter function for GPU ------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/nextafter.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nextafter, (double x, double y)) {
+ return __ocml_nextafter_f64(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/nextafterf.cpp b/src/math/amdgpu/nextafterf.cpp
new file mode 100644
index 000000000000..a97b990a61fc
--- /dev/null
+++ b/src/math/amdgpu/nextafterf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the nextafterf function for GPU -----------------===//
+//
+// Part of the LLVM Project, under the Apache 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/nextafterf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nextafterf, (float x, float y)) {
+ return __ocml_nextafter_f32(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/platform.h b/src/math/amdgpu/platform.h
new file mode 100644
index 000000000000..29d6cac1fa49
--- /dev/null
+++ b/src/math/amdgpu/platform.h
@@ -0,0 +1,54 @@
+//===-- AMDGPU specific platform definitions for math support -------------===//
+//
+// Part of the LLVM Project, under the Apache 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_AMDGPU_PLATFORM_H
+#define LLVM_LIBC_SRC_MATH_AMDGPU_PLATFORM_H
+
+#include "src/__support/macros/attributes.h"
+
+#include <stdint.h>
+
+namespace LIBC_NAMESPACE {
+
+// The ROCm device library uses control globals to alter codegen for the
+// different targets. To avoid needing to link them in manually we simply
+// define them here.
+extern "C" {
+
+// Disable unsafe math optimizations in the implementation.
+extern const LIBC_INLINE_VAR uint8_t __oclc_unsafe_math_opt = 0;
+
+// Disable denormalization at zero optimizations in the implementation.
+extern const LIBC_INLINE_VAR uint8_t __oclc_daz_opt = 0;
+
+// Disable rounding optimizations for 32-bit square roots.
+extern const LIBC_INLINE_VAR uint8_t __oclc_correctly_rounded_sqrt32 = 1;
+
+// Disable finite math optimizations.
+extern const LIBC_INLINE_VAR uint8_t __oclc_finite_only_opt = 0;
+
+// Set the ISA value to a high enough value that the ROCm device library math
+// functions will assume we have fast FMA operations among other features. This
+// is determined to be safe on all targets by looking at the source code.
+// https://github.com/ROCm/ROCm-Device-Libs/blob/amd-stg-open/ocml/src/opts.h
+extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9000;
+}
+
+// These aliases cause clang to emit the control constants with ODR linkage.
+// This allows us to link against the symbols without preventing them from being
+// optimized out or causing symbol collisions.
+[[gnu::alias("__oclc_unsafe_math_opt")]] const uint8_t __oclc_unsafe_math_opt__;
+[[gnu::alias("__oclc_daz_opt")]] const uint8_t __oclc_daz_opt__;
+[[gnu::alias("__oclc_correctly_rounded_sqrt32")]] const uint8_t
+ __oclc_correctly_rounded_sqrt32__;
+[[gnu::alias("__oclc_finite_only_opt")]] const uint8_t __oclc_finite_only_opt__;
+[[gnu::alias("__oclc_ISA_version")]] const uint32_t __oclc_ISA_version__;
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_AMDGPU_PLATFORM_H
diff --git a/src/math/gpu/vendor/pow.cpp b/src/math/amdgpu/pow.cpp
index d49f2610a691..e5056f67292d 100644
--- a/src/math/gpu/vendor/pow.cpp
+++ b/src/math/amdgpu/pow.cpp
@@ -9,12 +9,12 @@
#include "src/math/pow.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, pow, (double x, double y)) {
- return internal::pow(x, y);
+ return __ocml_pow_f64(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/powf.cpp b/src/math/amdgpu/powf.cpp
index 37e02d252b74..6114bcc642e1 100644
--- a/src/math/gpu/vendor/powf.cpp
+++ b/src/math/amdgpu/powf.cpp
@@ -9,12 +9,12 @@
#include "src/math/powf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
- return internal::powf(x, y);
+ return __ocml_pow_f32(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/remainder.cpp b/src/math/amdgpu/remainder.cpp
index 89b235f9c22a..89b235f9c22a 100644
--- a/src/math/gpu/remainder.cpp
+++ b/src/math/amdgpu/remainder.cpp
diff --git a/src/math/gpu/remainderf.cpp b/src/math/amdgpu/remainderf.cpp
index 9fee6f856dc8..9fee6f856dc8 100644
--- a/src/math/gpu/remainderf.cpp
+++ b/src/math/amdgpu/remainderf.cpp
diff --git a/src/math/amdgpu/remquo.cpp b/src/math/amdgpu/remquo.cpp
new file mode 100644
index 000000000000..d8074a9626ec
--- /dev/null
+++ b/src/math/amdgpu/remquo.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the GPU remquo 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/remquo.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, remquo, (double x, double y, int *quo)) {
+ int tmp;
+ double r = __ocml_remquo_f64(x, y, (gpu::Private<int> *)&tmp);
+ *quo = tmp;
+ return r;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/remquof.cpp b/src/math/amdgpu/remquof.cpp
new file mode 100644
index 000000000000..b6584dfb97c3
--- /dev/null
+++ b/src/math/amdgpu/remquof.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the GPU remquof 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/remquof.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, remquof, (float x, float y, int *quo)) {
+ int tmp;
+ float r = __ocml_remquo_f32(x, y, (gpu::Private<int> *)&tmp);
+ *quo = tmp;
+ return r;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/rint.cpp b/src/math/amdgpu/rint.cpp
index 44d494a8ed57..44d494a8ed57 100644
--- a/src/math/gpu/rint.cpp
+++ b/src/math/amdgpu/rint.cpp
diff --git a/src/math/gpu/rintf.cpp b/src/math/amdgpu/rintf.cpp
index daf98d943605..daf98d943605 100644
--- a/src/math/gpu/rintf.cpp
+++ b/src/math/amdgpu/rintf.cpp
diff --git a/src/math/gpu/round.cpp b/src/math/amdgpu/round.cpp
index 9d8b5582f040..9d8b5582f040 100644
--- a/src/math/gpu/round.cpp
+++ b/src/math/amdgpu/round.cpp
diff --git a/src/math/gpu/roundf.cpp b/src/math/amdgpu/roundf.cpp
index 8743e4eb7fb8..8743e4eb7fb8 100644
--- a/src/math/gpu/roundf.cpp
+++ b/src/math/amdgpu/roundf.cpp
diff --git a/src/math/amdgpu/scalbn.cpp b/src/math/amdgpu/scalbn.cpp
new file mode 100644
index 000000000000..c2a43e03a7bc
--- /dev/null
+++ b/src/math/amdgpu/scalbn.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the GPU scalbn 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/scalbn.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, scalbn, (double x, int y)) {
+ return __builtin_amdgcn_ldexp(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/scalbnf.cpp b/src/math/amdgpu/scalbnf.cpp
new file mode 100644
index 000000000000..63de26ccbc47
--- /dev/null
+++ b/src/math/amdgpu/scalbnf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the GPU scalbnf 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/scalbnf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, scalbnf, (float x, int y)) {
+ return __builtin_amdgcn_ldexpf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/sin.cpp b/src/math/amdgpu/sin.cpp
new file mode 100644
index 000000000000..dbc29a725db0
--- /dev/null
+++ b/src/math/amdgpu/sin.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the sin function for GPU ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sin.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, sin, (double x)) { return __ocml_sin_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/sincos.cpp b/src/math/amdgpu/sincos.cpp
new file mode 100644
index 000000000000..7cdd0d1f9769
--- /dev/null
+++ b/src/math/amdgpu/sincos.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the sincos function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sincos.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sinptr, double *cosptr)) {
+ *sinptr = __ocml_sincos_f64(x, cosptr);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sincosf.cpp b/src/math/amdgpu/sincosf.cpp
index 17892ceb107d..37a5e2a6d11c 100644
--- a/src/math/gpu/vendor/sincosf.cpp
+++ b/src/math/amdgpu/sincosf.cpp
@@ -9,12 +9,12 @@
#include "src/math/sincosf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinptr, float *cosptr)) {
- return internal::sincosf(x, sinptr, cosptr);
+ *sinptr = __ocml_sincos_f32(x, cosptr);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/sinf.cpp b/src/math/amdgpu/sinf.cpp
new file mode 100644
index 000000000000..cda2c626f8ac
--- /dev/null
+++ b/src/math/amdgpu/sinf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the sinf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sinf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, sinf, (float x)) { return __ocml_sin_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/sinh.cpp b/src/math/amdgpu/sinh.cpp
index 054e046f2abd..66cacd19e463 100644
--- a/src/math/gpu/sinh.cpp
+++ b/src/math/amdgpu/sinh.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of the GPU sinh function ---------------------------===//
+//===-- Implementation of the sinh function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,8 +9,10 @@
#include "src/math/sinh.h"
#include "src/__support/common.h"
+#include "declarations.h"
+
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return __builtin_sinh(x); }
+LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return __ocml_sinh_f64(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/sinhf.cpp b/src/math/amdgpu/sinhf.cpp
new file mode 100644
index 000000000000..5d3f5ea6b36a
--- /dev/null
+++ b/src/math/amdgpu/sinhf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the sinhf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sinhf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return __ocml_sinh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/sqrt.cpp b/src/math/amdgpu/sqrt.cpp
index 60ca5af4987b..60ca5af4987b 100644
--- a/src/math/gpu/sqrt.cpp
+++ b/src/math/amdgpu/sqrt.cpp
diff --git a/src/math/gpu/sqrtf.cpp b/src/math/amdgpu/sqrtf.cpp
index e17f942a4d5f..e17f942a4d5f 100644
--- a/src/math/gpu/sqrtf.cpp
+++ b/src/math/amdgpu/sqrtf.cpp
diff --git a/src/math/gpu/tan.cpp b/src/math/amdgpu/tan.cpp
index d02b10635612..6121a9319a2a 100644
--- a/src/math/gpu/tan.cpp
+++ b/src/math/amdgpu/tan.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of the GPU tan function ----------------------------===//
+//===-- Implementation of the tan function for GPU ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,8 +9,10 @@
#include "src/math/tan.h"
#include "src/__support/common.h"
+#include "declarations.h"
+
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, tan, (double x)) { return __builtin_tan(x); }
+LLVM_LIBC_FUNCTION(double, tan, (double x)) { return __ocml_tan_f64(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/tanf.cpp b/src/math/amdgpu/tanf.cpp
new file mode 100644
index 000000000000..fdd83ee7aeb9
--- /dev/null
+++ b/src/math/amdgpu/tanf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the tanf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/tanf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, tanf, (float x)) { return __ocml_tan_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/tanh.cpp b/src/math/amdgpu/tanh.cpp
index 778e883acba0..25a9c2954bf3 100644
--- a/src/math/gpu/tanh.cpp
+++ b/src/math/amdgpu/tanh.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of the GPU tanh function ---------------------------===//
+//===-- Implementation of the tanh function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,8 +9,10 @@
#include "src/math/tanh.h"
#include "src/__support/common.h"
+#include "declarations.h"
+
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return __builtin_tanh(x); }
+LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return __ocml_tanh_f64(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/tanhf.cpp b/src/math/amdgpu/tanhf.cpp
new file mode 100644
index 000000000000..a4bfd2095eb3
--- /dev/null
+++ b/src/math/amdgpu/tanhf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the tanhf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/tanhf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { return __ocml_tanh_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/tgamma.cpp b/src/math/amdgpu/tgamma.cpp
new file mode 100644
index 000000000000..10f58d566f88
--- /dev/null
+++ b/src/math/amdgpu/tgamma.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU tgamma 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/tgamma.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, tgamma, (double x)) { return __ocml_tgamma_f64(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/amdgpu/tgammaf.cpp b/src/math/amdgpu/tgammaf.cpp
new file mode 100644
index 000000000000..e7d22059a7c4
--- /dev/null
+++ b/src/math/amdgpu/tgammaf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU tgammaf 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/tgammaf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, tgammaf, (float x)) { return __ocml_tgamma_f32(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/trunc.cpp b/src/math/amdgpu/trunc.cpp
index 773600f0f250..773600f0f250 100644
--- a/src/math/gpu/trunc.cpp
+++ b/src/math/amdgpu/trunc.cpp
diff --git a/src/math/gpu/truncf.cpp b/src/math/amdgpu/truncf.cpp
index 534797a3e586..534797a3e586 100644
--- a/src/math/gpu/truncf.cpp
+++ b/src/math/amdgpu/truncf.cpp
diff --git a/src/math/canonicalize.h b/src/math/canonicalize.h
new file mode 100644
index 000000000000..b7b5959fb667
--- /dev/null
+++ b/src/math/canonicalize.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalize -------------------*- 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_CANONICALIZE_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZE_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalize(double *cx, const double *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZE_H
diff --git a/src/math/canonicalizef.h b/src/math/canonicalizef.h
new file mode 100644
index 000000000000..556607f13349
--- /dev/null
+++ b/src/math/canonicalizef.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalizef ------------------*- 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_CANONICALIZEF_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEF_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizef(float *cx, const float *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEF_H
diff --git a/src/math/canonicalizef128.h b/src/math/canonicalizef128.h
new file mode 100644
index 000000000000..6db800947537
--- /dev/null
+++ b/src/math/canonicalizef128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for canonicalizef128 ---------------*-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_CANONICALIZEF128_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizef128(float128 *cx, const float128 *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
diff --git a/src/math/canonicalizel.h b/src/math/canonicalizel.h
new file mode 100644
index 000000000000..1cab29e8e8b1
--- /dev/null
+++ b/src/math/canonicalizel.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalizel ------------------*- 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_CANONICALIZEL_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEL_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizel(long double *cx, const long double *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEL_H
diff --git a/src/math/ceilf128.h b/src/math/ceilf128.h
new file mode 100644
index 000000000000..b0c4020718b2
--- /dev/null
+++ b/src/math/ceilf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ceilf128 ----------------------*- 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_CEILF128_H
+#define LLVM_LIBC_SRC_MATH_CEILF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 ceilf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CEILF128_H
diff --git a/src/math/copysignf128.h b/src/math/copysignf128.h
index 5e40657de33b..06c194985d72 100644
--- a/src/math/copysignf128.h
+++ b/src/math/copysignf128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_MATH_COPYSIGNF128_H
#define LLVM_LIBC_SRC_MATH_COPYSIGNF128_H
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE {
@@ -17,4 +17,4 @@ float128 copysignf128(float128 x, float128 y);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_MATH_COPYSIGN_H
+#endif // LLVM_LIBC_SRC_MATH_COPYSIGNF128_H
diff --git a/src/math/exp2m1f.h b/src/math/exp2m1f.h
new file mode 100644
index 000000000000..0eaf6b00e958
--- /dev/null
+++ b/src/math/exp2m1f.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for exp2m1f -----------------------*- 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_EXP2M1F_H
+#define LLVM_LIBC_SRC_MATH_EXP2M1F_H
+
+namespace LIBC_NAMESPACE {
+
+float exp2m1f(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_EXP2M1F_H
diff --git a/src/math/fabsf128.h b/src/math/fabsf128.h
index 5999757decfd..0a275025a5cf 100644
--- a/src/math/fabsf128.h
+++ b/src/math/fabsf128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_MATH_FABSF128_H
#define LLVM_LIBC_SRC_MATH_FABSF128_H
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/fdimf128.h b/src/math/fdimf128.h
new file mode 100644
index 000000000000..f0485aba4822
--- /dev/null
+++ b/src/math/fdimf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fdimf128 ----------------------*- 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_FDIMF128_H
+#define LLVM_LIBC_SRC_MATH_FDIMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fdimf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FDIMF128_H
diff --git a/src/math/floorf128.h b/src/math/floorf128.h
new file mode 100644
index 000000000000..b97c4b6c6cec
--- /dev/null
+++ b/src/math/floorf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for floorf128 ---------------------*- 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_FLOORF128_H
+#define LLVM_LIBC_SRC_MATH_FLOORF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 floorf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FLOORF128_H
diff --git a/src/math/fmaxf128.h b/src/math/fmaxf128.h
index 39eaaf616dd5..a4407d9655af 100644
--- a/src/math/fmaxf128.h
+++ b/src/math/fmaxf128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_MATH_FMAXF128_H
#define LLVM_LIBC_SRC_MATH_FMAXF128_H
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/fmaximum.h b/src/math/fmaximum.h
new file mode 100644
index 000000000000..8eac02b17b79
--- /dev/null
+++ b/src/math/fmaximum.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum --------------------------*- 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_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fmaximum(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_H
diff --git a/src/math/fmaximum_mag.h b/src/math/fmaximum_mag.h
new file mode 100644
index 000000000000..31b7c0fcf7ee
--- /dev/null
+++ b/src/math/fmaximum_mag.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_mag------------------------*- 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_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_H
+
+namespace LIBC_NAMESPACE {
+
+double fmaximum_mag(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_H
diff --git a/src/math/fmaximum_mag_num.h b/src/math/fmaximum_mag_num.h
new file mode 100644
index 000000000000..c4ff243846e0
--- /dev/null
+++ b/src/math/fmaximum_mag_num.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fmaximum_mag_num---------------*- 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_NUM_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fmaximum_mag_num(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUM_H
diff --git a/src/math/fmaximum_mag_numf.h b/src/math/fmaximum_mag_numf.h
new file mode 100644
index 000000000000..702903ab8bcf
--- /dev/null
+++ b/src/math/fmaximum_mag_numf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_mag_numf ----------------------*- 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_NUMF_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fmaximum_mag_numf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF_H
diff --git a/src/math/fmaximum_mag_numf128.h b/src/math/fmaximum_mag_numf128.h
new file mode 100644
index 000000000000..2afae7fc37c4
--- /dev/null
+++ b/src/math/fmaximum_mag_numf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_mag_numf128 -------------------*- 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_NUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fmaximum_mag_numf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF128_H
diff --git a/src/math/fmaximum_mag_numl.h b/src/math/fmaximum_mag_numl.h
new file mode 100644
index 000000000000..32f9ae9708a6
--- /dev/null
+++ b/src/math/fmaximum_mag_numl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_mag_numl ----------------------*- 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_NUML_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fmaximum_mag_numl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUML_H
diff --git a/src/math/fmaximum_magf.h b/src/math/fmaximum_magf.h
new file mode 100644
index 000000000000..1bfcc795f8f8
--- /dev/null
+++ b/src/math/fmaximum_magf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_magf -------------------------*- 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_MAGF_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF_H
+
+namespace LIBC_NAMESPACE {
+
+float fmaximum_magf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF_H
diff --git a/src/math/fmaximum_magf128.h b/src/math/fmaximum_magf128.h
new file mode 100644
index 000000000000..23c466b74cce
--- /dev/null
+++ b/src/math/fmaximum_magf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_magf128 ----------------------*- 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_MAGF128_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fmaximum_magf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF128_H
diff --git a/src/math/fmaximum_magl.h b/src/math/fmaximum_magl.h
new file mode 100644
index 000000000000..23b283cb5dbc
--- /dev/null
+++ b/src/math/fmaximum_magl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_magl -------------------------*- 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_MAGL_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fmaximum_magl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGL_H
diff --git a/src/math/fmaximum_num.h b/src/math/fmaximum_num.h
new file mode 100644
index 000000000000..ce3ce12ca64b
--- /dev/null
+++ b/src/math/fmaximum_num.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_num--------------------------*- 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_NUM_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fmaximum_num(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUM_H
diff --git a/src/math/fmaximum_numf.h b/src/math/fmaximum_numf.h
new file mode 100644
index 000000000000..b3243ed16be9
--- /dev/null
+++ b/src/math/fmaximum_numf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_numf -------------------------*- 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_NUMF_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fmaximum_numf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF_H
diff --git a/src/math/fmaximum_numf128.h b/src/math/fmaximum_numf128.h
new file mode 100644
index 000000000000..d55183ce88cc
--- /dev/null
+++ b/src/math/fmaximum_numf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_numf128 ----------------------*- 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_NUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fmaximum_numf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF128_H
diff --git a/src/math/fmaximum_numl.h b/src/math/fmaximum_numl.h
new file mode 100644
index 000000000000..f668cbdf7315
--- /dev/null
+++ b/src/math/fmaximum_numl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximum_numl -------------------------*- 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_NUML_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fmaximum_numl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUML_H
diff --git a/src/math/fmaximumf.h b/src/math/fmaximumf.h
new file mode 100644
index 000000000000..4eee696ce152
--- /dev/null
+++ b/src/math/fmaximumf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximumf -------------------------*- 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_FMAXIMUMF_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fmaximumf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUMF_H
diff --git a/src/math/fmaximumf128.h b/src/math/fmaximumf128.h
new file mode 100644
index 000000000000..4a214ef096e1
--- /dev/null
+++ b/src/math/fmaximumf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximumf128 ----------------------*- 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_FMAXIMUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fmaximumf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUMF128_H
diff --git a/src/math/fmaximuml.h b/src/math/fmaximuml.h
new file mode 100644
index 000000000000..ba8a8b12110c
--- /dev/null
+++ b/src/math/fmaximuml.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fmaximuml -------------------------*- 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_FMAXIMUML_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fmaximuml(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUML_H
diff --git a/src/math/fminf128.h b/src/math/fminf128.h
index b3d1bec8e2ad..d2ed593250a4 100644
--- a/src/math/fminf128.h
+++ b/src/math/fminf128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_MATH_FMINF128_H
#define LLVM_LIBC_SRC_MATH_FMINF128_H
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/fminimum.h b/src/math/fminimum.h
new file mode 100644
index 000000000000..9d39b1bdd3db
--- /dev/null
+++ b/src/math/fminimum.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum -------------------------*- 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_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fminimum(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_H
diff --git a/src/math/fminimum_mag.h b/src/math/fminimum_mag.h
new file mode 100644
index 000000000000..10b242e6026e
--- /dev/null
+++ b/src/math/fminimum_mag.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_mag--------------------------*- 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_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_H
+
+namespace LIBC_NAMESPACE {
+
+double fminimum_mag(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_H
diff --git a/src/math/fminimum_mag_num.h b/src/math/fminimum_mag_num.h
new file mode 100644
index 000000000000..eb1823018851
--- /dev/null
+++ b/src/math/fminimum_mag_num.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_mag_num------------------------*- 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_NUM_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fminimum_mag_num(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMH
diff --git a/src/math/fminimum_mag_numf.h b/src/math/fminimum_mag_numf.h
new file mode 100644
index 000000000000..809199091139
--- /dev/null
+++ b/src/math/fminimum_mag_numf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_mag_numf ----------------------*- 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_NUMF_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fminimum_mag_numf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF_H
diff --git a/src/math/fminimum_mag_numf128.h b/src/math/fminimum_mag_numf128.h
new file mode 100644
index 000000000000..803c5e641d17
--- /dev/null
+++ b/src/math/fminimum_mag_numf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_mag_numf128 -------------------*- 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_NUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fminimum_mag_numf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF128_H
diff --git a/src/math/fminimum_mag_numl.h b/src/math/fminimum_mag_numl.h
new file mode 100644
index 000000000000..fdbb18328069
--- /dev/null
+++ b/src/math/fminimum_mag_numl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_mag_numl ----------------------*- 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_NUML_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fminimum_mag_numl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUML_H
diff --git a/src/math/fminimum_magf.h b/src/math/fminimum_magf.h
new file mode 100644
index 000000000000..6209340074d2
--- /dev/null
+++ b/src/math/fminimum_magf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_magf -------------------------*- 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_MAGF_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF_H
+
+namespace LIBC_NAMESPACE {
+
+float fminimum_magf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF_H
diff --git a/src/math/fminimum_magf128.h b/src/math/fminimum_magf128.h
new file mode 100644
index 000000000000..05bd163be97c
--- /dev/null
+++ b/src/math/fminimum_magf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_magf128 ----------------------*- 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_MAGF128_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fminimum_magf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF128_H
diff --git a/src/math/fminimum_magl.h b/src/math/fminimum_magl.h
new file mode 100644
index 000000000000..bcda35ce3bd2
--- /dev/null
+++ b/src/math/fminimum_magl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_magl -------------------------*- 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_MAGL_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fminimum_magl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGL_H
diff --git a/src/math/fminimum_num.h b/src/math/fminimum_num.h
new file mode 100644
index 000000000000..4c864cba8487
--- /dev/null
+++ b/src/math/fminimum_num.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_num--------------------------*- 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_NUM_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUM_H
+
+namespace LIBC_NAMESPACE {
+
+double fminimum_num(double x, double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUM_H
diff --git a/src/math/fminimum_numf.h b/src/math/fminimum_numf.h
new file mode 100644
index 000000000000..ac4b08b292be
--- /dev/null
+++ b/src/math/fminimum_numf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_numf -------------------------*- 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_NUMF_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fminimum_numf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF_H
diff --git a/src/math/fminimum_numf128.h b/src/math/fminimum_numf128.h
new file mode 100644
index 000000000000..00f8960ff127
--- /dev/null
+++ b/src/math/fminimum_numf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_numf128 ----------------------*- 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_NUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fminimum_numf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF128_H
diff --git a/src/math/fminimum_numl.h b/src/math/fminimum_numl.h
new file mode 100644
index 000000000000..0da204e72c74
--- /dev/null
+++ b/src/math/fminimum_numl.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimum_numl -------------------------*- 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_NUML_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fminimum_numl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUML_H
diff --git a/src/math/fminimumf.h b/src/math/fminimumf.h
new file mode 100644
index 000000000000..424309f3a531
--- /dev/null
+++ b/src/math/fminimumf.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimumf -------------------------*- 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_FMINIMUMF_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUMF_H
+
+namespace LIBC_NAMESPACE {
+
+float fminimumf(float x, float y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUMF_H
diff --git a/src/math/fminimumf128.h b/src/math/fminimumf128.h
new file mode 100644
index 000000000000..7ff019072737
--- /dev/null
+++ b/src/math/fminimumf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimumf128 ----------------------*- 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_FMINIMUMF128_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUMF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fminimumf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUMF128_H
diff --git a/src/math/fminimuml.h b/src/math/fminimuml.h
new file mode 100644
index 000000000000..b9cc321354a2
--- /dev/null
+++ b/src/math/fminimuml.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for fminimuml -------------------------*- 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_FMINIMUML_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUML_H
+
+namespace LIBC_NAMESPACE {
+
+long double fminimuml(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUML_H
diff --git a/src/math/fmodf128.h b/src/math/fmodf128.h
new file mode 100644
index 000000000000..b3242705f025
--- /dev/null
+++ b/src/math/fmodf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fmodf128 ----------------------*- 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_FMODF128_H
+#define LLVM_LIBC_SRC_MATH_FMODF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fmodf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMODF128_H
diff --git a/src/math/fmodl.h b/src/math/fmodl.h
new file mode 100644
index 000000000000..f259ddb238a8
--- /dev/null
+++ b/src/math/fmodl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fmodl -------------------------*- 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_FMODL_H
+#define LLVM_LIBC_SRC_MATH_FMODL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fmodl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FMODL_H
diff --git a/src/math/frexpf128.h b/src/math/frexpf128.h
new file mode 100644
index 000000000000..55c4a47cc80c
--- /dev/null
+++ b/src/math/frexpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for frexpf128 ---------------------*- 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_FREXPF128_H
+#define LLVM_LIBC_SRC_MATH_FREXPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 frexpf128(float128 x, int *exp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FREXPF128_H
diff --git a/src/math/fromfp.h b/src/math/fromfp.h
new file mode 100644
index 000000000000..d3de2dd34608
--- /dev/null
+++ b/src/math/fromfp.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfp ------------------------*- 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_FROMFP_H
+#define LLVM_LIBC_SRC_MATH_FROMFP_H
+
+namespace LIBC_NAMESPACE {
+
+double fromfp(double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFP_H
diff --git a/src/math/fromfpf.h b/src/math/fromfpf.h
new file mode 100644
index 000000000000..11d432148d01
--- /dev/null
+++ b/src/math/fromfpf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpf -----------------------*- 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_FROMFPF_H
+#define LLVM_LIBC_SRC_MATH_FROMFPF_H
+
+namespace LIBC_NAMESPACE {
+
+float fromfpf(float x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPF_H
diff --git a/src/math/fromfpf128.h b/src/math/fromfpf128.h
new file mode 100644
index 000000000000..5f85fde570a0
--- /dev/null
+++ b/src/math/fromfpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fromfpf128 --------------------*- 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_FROMFPF128_H
+#define LLVM_LIBC_SRC_MATH_FROMFPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fromfpf128(float128 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPF128_H
diff --git a/src/math/fromfpl.h b/src/math/fromfpl.h
new file mode 100644
index 000000000000..dd8e1eebdea9
--- /dev/null
+++ b/src/math/fromfpl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpl -----------------------*- 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_FROMFPL_H
+#define LLVM_LIBC_SRC_MATH_FROMFPL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fromfpl(long double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPL_H
diff --git a/src/math/fromfpx.h b/src/math/fromfpx.h
new file mode 100644
index 000000000000..3fc96e1e648b
--- /dev/null
+++ b/src/math/fromfpx.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpx -----------------------*- 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_FROMFPX_H
+#define LLVM_LIBC_SRC_MATH_FROMFPX_H
+
+namespace LIBC_NAMESPACE {
+
+double fromfpx(double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPX_H
diff --git a/src/math/fromfpxf.h b/src/math/fromfpxf.h
new file mode 100644
index 000000000000..b55bc4c75139
--- /dev/null
+++ b/src/math/fromfpxf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpxf ----------------------*- 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_FROMFPXF_H
+#define LLVM_LIBC_SRC_MATH_FROMFPXF_H
+
+namespace LIBC_NAMESPACE {
+
+float fromfpxf(float x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPXF_H
diff --git a/src/math/fromfpxf128.h b/src/math/fromfpxf128.h
new file mode 100644
index 000000000000..88932646cdcc
--- /dev/null
+++ b/src/math/fromfpxf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fromfpxf128 -------------------*- 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_FROMFPXF128_H
+#define LLVM_LIBC_SRC_MATH_FROMFPXF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fromfpxf128(float128 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPXF128_H
diff --git a/src/math/fromfpxl.h b/src/math/fromfpxl.h
new file mode 100644
index 000000000000..545288834b8f
--- /dev/null
+++ b/src/math/fromfpxl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpxl ----------------------*- 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_FROMFPXL_H
+#define LLVM_LIBC_SRC_MATH_FROMFPXL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fromfpxl(long double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPXL_H
diff --git a/src/math/generic/acosf.cpp b/src/math/generic/acosf.cpp
index 0c1fdbc68693..e6e28d43ef61 100644
--- a/src/math/generic/acosf.cpp
+++ b/src/math/generic/acosf.cpp
@@ -38,7 +38,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
uint32_t x_uint = xbits.uintval();
uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
diff --git a/src/math/generic/acoshf.cpp b/src/math/generic/acoshf.cpp
index 54b66bf42fc6..a4a75a7b0438 100644
--- a/src/math/generic/acoshf.cpp
+++ b/src/math/generic/acoshf.cpp
@@ -33,12 +33,8 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
}
if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
- // Check for exceptional values.
- uint32_t x_abs = xbits.abs().uintval();
- if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
- // x is +inf or NaN.
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
return x;
- }
// Helper functions to set results for exceptional cases.
auto round_result_slightly_down = [](float r) -> float {
diff --git a/src/math/generic/asinf.cpp b/src/math/generic/asinf.cpp
index 6e3a27238ac9..d9133333d256 100644
--- a/src/math/generic/asinf.cpp
+++ b/src/math/generic/asinf.cpp
@@ -44,7 +44,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
uint32_t x_uint = xbits.uintval();
uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
diff --git a/src/math/generic/asinhf.cpp b/src/math/generic/asinhf.cpp
index ac059910b4ef..6e351786e3ec 100644
--- a/src/math/generic/asinhf.cpp
+++ b/src/math/generic/asinhf.cpp
@@ -59,10 +59,8 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
};
if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) {
- if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
- // x is +-inf or nan
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
return x;
- }
// Exceptional cases when x > 2^24.
switch (x_abs) {
diff --git a/src/math/generic/atan2f.cpp b/src/math/generic/atan2f.cpp
new file mode 100644
index 000000000000..b79410dbf66e
--- /dev/null
+++ b/src/math/generic/atan2f.cpp
@@ -0,0 +1,306 @@
+//===-- Single-precision atan2f 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/atan2f.h"
+#include "inv_trigf_utils.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.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/FPUtil/rounding_mode.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+
+namespace LIBC_NAMESPACE {
+
+namespace {
+
+// Look up tables for accurate pass:
+
+// atan(i/16) with i = 0..16, generated by Sollya with:
+// > for i from 0 to 16 do {
+// a = round(atan(i/16), D, RN);
+// b = round(atan(i/16) - a, D, RN);
+// print("{", b, ",", a, "},");
+// };
+constexpr fputil::DoubleDouble ATAN_I[17] = {
+ {0.0, 0.0},
+ {-0x1.c934d86d23f1dp-60, 0x1.ff55bb72cfdeap-5},
+ {-0x1.cd37686760c17p-59, 0x1.fd5ba9aac2f6ep-4},
+ {0x1.347b0b4f881cap-58, 0x1.7b97b4bce5b02p-3},
+ {0x1.8ab6e3cf7afbdp-57, 0x1.f5b75f92c80ddp-3},
+ {-0x1.963a544b672d8p-57, 0x1.362773707ebccp-2},
+ {-0x1.c63aae6f6e918p-56, 0x1.6f61941e4def1p-2},
+ {-0x1.24dec1b50b7ffp-56, 0x1.a64eec3cc23fdp-2},
+ {0x1.a2b7f222f65e2p-56, 0x1.dac670561bb4fp-2},
+ {-0x1.d5b495f6349e6p-56, 0x1.0657e94db30dp-1},
+ {-0x1.928df287a668fp-58, 0x1.1e00babdefeb4p-1},
+ {0x1.1021137c71102p-55, 0x1.345f01cce37bbp-1},
+ {0x1.2419a87f2a458p-56, 0x1.4978fa3269ee1p-1},
+ {0x1.0028e4bc5e7cap-57, 0x1.5d58987169b18p-1},
+ {-0x1.8c34d25aadef6p-56, 0x1.700a7c5784634p-1},
+ {-0x1.bf76229d3b917p-56, 0x1.819d0b7158a4dp-1},
+ {0x1.1a62633145c07p-55, 0x1.921fb54442d18p-1},
+};
+
+// Taylor polynomial, generated by Sollya with:
+// > for i from 0 to 8 do {
+// j = (-1)^(i + 1)/(2*i + 1);
+// a = round(j, D, RN);
+// b = round(j - a, D, RN);
+// print("{", b, ",", a, "},");
+// };
+constexpr fputil::DoubleDouble COEFFS[9] = {
+ {0.0, 1.0}, // 1
+ {-0x1.5555555555555p-56, -0x1.5555555555555p-2}, // -1/3
+ {-0x1.999999999999ap-57, 0x1.999999999999ap-3}, // 1/5
+ {-0x1.2492492492492p-57, -0x1.2492492492492p-3}, // -1/7
+ {0x1.c71c71c71c71cp-58, 0x1.c71c71c71c71cp-4}, // 1/9
+ {0x1.745d1745d1746p-59, -0x1.745d1745d1746p-4}, // -1/11
+ {-0x1.3b13b13b13b14p-58, 0x1.3b13b13b13b14p-4}, // 1/13
+ {-0x1.1111111111111p-60, -0x1.1111111111111p-4}, // -1/15
+ {0x1.e1e1e1e1e1e1ep-61, 0x1.e1e1e1e1e1e1ep-5}, // 1/17
+};
+
+// Veltkamp's splitting of a double precision into hi + lo, where the hi part is
+// slightly smaller than an even split, so that the product of
+// hi * (s1 * k + s2) is exact,
+// where:
+// s1, s2 are single precsion,
+// 1/16 <= s1/s2 <= 1
+// 1/16 <= k <= 1 is an integer.
+// So the maximal precision of (s1 * k + s2) is:
+// prec(s1 * k + s2) = 2 + log2(msb(s2)) - log2(lsb(k_d * s1))
+// = 2 + log2(msb(s1)) + 4 - log2(lsb(k_d)) - log2(lsb(s1))
+// = 2 + log2(lsb(s1)) + 23 + 4 - (-4) - log2(lsb(s1))
+// = 33.
+// Thus, the Veltkamp splitting constant is C = 2^33 + 1.
+// This is used when FMA instruction is not available.
+[[maybe_unused]] constexpr fputil::DoubleDouble split_d(double a) {
+ fputil::DoubleDouble r{0.0, 0.0};
+ constexpr double C = 0x1.0p33 + 1.0;
+ double t1 = C * a;
+ double t2 = a - t1;
+ r.hi = t1 + t2;
+ r.lo = a - r.hi;
+ return r;
+}
+
+// Compute atan( num_d / den_d ) in double-double precision.
+// num_d = min(|x|, |y|)
+// den_d = max(|x|, |y|)
+// q_d = num_d / den_d
+// idx, k_d = round( 2^4 * num_d / den_d )
+// final_sign = sign of the final result
+// const_term = the constant term in the final expression.
+float atan2f_double_double(double num_d, double den_d, double q_d, int idx,
+ double k_d, double final_sign,
+ const fputil::DoubleDouble &const_term) {
+ fputil::DoubleDouble q;
+ double num_r, den_r;
+
+ if (idx != 0) {
+ // The following range reduction is accurate even without fma for
+ // 1/16 <= n/d <= 1.
+ // atan(n/d) - atan(idx/16) = atan((n/d - idx/16) / (1 + (n/d) * (idx/16)))
+ // = atan((n - d*(idx/16)) / (d + n*idx/16))
+ k_d *= 0x1.0p-4;
+ num_r = fputil::multiply_add(k_d, -den_d, num_d); // Exact
+ den_r = fputil::multiply_add(k_d, num_d, den_d); // Exact
+ q.hi = num_r / den_r;
+ } else {
+ // For 0 < n/d < 1/16, we just need to calculate the lower part of their
+ // quotient.
+ q.hi = q_d;
+ num_r = num_d;
+ den_r = den_d;
+ }
+#ifdef LIBC_TARGET_CPU_HAS_FMA
+ q.lo = fputil::multiply_add(q.hi, -den_r, num_r) / den_r;
+#else
+ // Compute `(num_r - q.hi * den_r) / den_r` accurately without FMA
+ // instructions.
+ fputil::DoubleDouble q_hi_dd = split_d(q.hi);
+ double t1 = fputil::multiply_add(q_hi_dd.hi, -den_r, num_r); // Exact
+ double t2 = fputil::multiply_add(q_hi_dd.lo, -den_r, t1);
+ q.lo = t2 / den_r;
+#endif // LIBC_TARGET_CPU_HAS_FMA
+
+ // Taylor polynomial, evaluating using Horner's scheme:
+ // P = x - x^3/3 + x^5/5 -x^7/7 + x^9/9 - x^11/11 + x^13/13 - x^15/15
+ // + x^17/17
+ // = x*(1 + x^2*(-1/3 + x^2*(1/5 + x^2*(-1/7 + x^2*(1/9 + x^2*
+ // *(-1/11 + x^2*(1/13 + x^2*(-1/15 + x^2 * 1/17))))))))
+ fputil::DoubleDouble q2 = fputil::quick_mult(q, q);
+ fputil::DoubleDouble p_dd =
+ fputil::polyeval(q2, COEFFS[0], COEFFS[1], COEFFS[2], COEFFS[3],
+ COEFFS[4], COEFFS[5], COEFFS[6], COEFFS[7], COEFFS[8]);
+ fputil::DoubleDouble r_dd =
+ fputil::add(const_term, fputil::multiply_add(q, p_dd, ATAN_I[idx]));
+ r_dd.hi *= final_sign;
+ r_dd.lo *= final_sign;
+
+ // Make sure the sum is normalized:
+ fputil::DoubleDouble rr = fputil::exact_add(r_dd.hi, r_dd.lo);
+ // Round to odd.
+ uint64_t rr_bits = cpp::bit_cast<uint64_t>(rr.hi);
+ if (LIBC_UNLIKELY(((rr_bits & 0xfff'ffff) == 0) && (rr.lo != 0.0))) {
+ Sign hi_sign = fputil::FPBits<double>(rr.hi).sign();
+ Sign lo_sign = fputil::FPBits<double>(rr.lo).sign();
+ if (hi_sign == lo_sign) {
+ ++rr_bits;
+ } else if ((rr_bits & fputil::FPBits<double>::FRACTION_MASK) > 0) {
+ --rr_bits;
+ }
+ }
+
+ return static_cast<float>(cpp::bit_cast<double>(rr_bits));
+}
+
+} // anonymous namespace
+
+// There are several range reduction steps we can take for atan2(y, x) as
+// follow:
+
+// * Range reduction 1: signness
+// atan2(y, x) will return a number between -PI and PI representing the angle
+// forming by the 0x axis and the vector (x, y) on the 0xy-plane.
+// In particular, we have that:
+// atan2(y, x) = atan( y/x ) if x >= 0 and y >= 0 (I-quadrant)
+// = pi + atan( y/x ) if x < 0 and y >= 0 (II-quadrant)
+// = -pi + atan( y/x ) if x < 0 and y < 0 (III-quadrant)
+// = atan( y/x ) if x >= 0 and y < 0 (IV-quadrant)
+// Since atan function is odd, we can use the formula:
+// atan(-u) = -atan(u)
+// to adjust the above conditions a bit further:
+// atan2(y, x) = atan( |y|/|x| ) if x >= 0 and y >= 0 (I-quadrant)
+// = pi - atan( |y|/|x| ) if x < 0 and y >= 0 (II-quadrant)
+// = -pi + atan( |y|/|x| ) if x < 0 and y < 0 (III-quadrant)
+// = -atan( |y|/|x| ) if x >= 0 and y < 0 (IV-quadrant)
+// Which can be simplified to:
+// atan2(y, x) = sign(y) * atan( |y|/|x| ) if x >= 0
+// = sign(y) * (pi - atan( |y|/|x| )) if x < 0
+
+// * Range reduction 2: reciprocal
+// Now that the argument inside atan is positive, we can use the formula:
+// atan(1/x) = pi/2 - atan(x)
+// to make the argument inside atan <= 1 as follow:
+// atan2(y, x) = sign(y) * atan( |y|/|x|) if 0 <= |y| <= x
+// = sign(y) * (pi/2 - atan( |x|/|y| ) if 0 <= x < |y|
+// = sign(y) * (pi - atan( |y|/|x| )) if 0 <= |y| <= -x
+// = sign(y) * (pi/2 + atan( |x|/|y| )) if 0 <= -x < |y|
+
+// * Range reduction 3: look up table.
+// After the previous two range reduction steps, we reduce the problem to
+// compute atan(u) with 0 <= u <= 1, or to be precise:
+// atan( n / d ) where n = min(|x|, |y|) and d = max(|x|, |y|).
+// An accurate polynomial approximation for the whole [0, 1] input range will
+// require a very large degree. To make it more efficient, we reduce the input
+// range further by finding an integer idx such that:
+// | n/d - idx/16 | <= 1/32.
+// In particular,
+// idx := 2^-4 * round(2^4 * n/d)
+// Then for the fast pass, we find a polynomial approximation for:
+// atan( n/d ) ~ atan( idx/16 ) + (n/d - idx/16) * Q(n/d - idx/16)
+// For the accurate pass, we use the addition formula:
+// atan( n/d ) - atan( idx/16 ) = atan( (n/d - idx/16)/(1 + (n*idx)/(16*d)) )
+// = atan( (n - d * idx/16)/(d + n * idx/16) )
+// And finally we use Taylor polynomial to compute the RHS in the accurate pass:
+// atan(u) ~ P(u) = u - u^3/3 + u^5/5 - u^7/7 + u^9/9 - u^11/11 + u^13/13 -
+// - u^15/15 + u^17/17
+// It's error in double-double precision is estimated in Sollya to be:
+// > P = x - x^3/3 + x^5/5 -x^7/7 + x^9/9 - x^11/11 + x^13/13 - x^15/15
+// + x^17/17;
+// > dirtyinfnorm(atan(x) - P, [-2^-5, 2^-5]);
+// 0x1.aec6f...p-100
+// which is about rounding errors of double-double (2^-104).
+
+LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) {
+ using FPBits = typename fputil::FPBits<float>;
+ constexpr double IS_NEG[2] = {1.0, -1.0};
+ constexpr double PI = 0x1.921fb54442d18p1;
+ constexpr double PI_LO = 0x1.1a62633145c07p-53;
+ constexpr double PI_OVER_4 = 0x1.921fb54442d18p-1;
+ constexpr double PI_OVER_2 = 0x1.921fb54442d18p0;
+ constexpr double THREE_PI_OVER_4 = 0x1.2d97c7f3321d2p+1;
+ // Adjustment for constant term:
+ // CONST_ADJ[x_sign][y_sign][recip]
+ constexpr fputil::DoubleDouble CONST_ADJ[2][2][2] = {
+ {{{0.0, 0.0}, {-PI_LO / 2, -PI_OVER_2}},
+ {{-0.0, -0.0}, {-PI_LO / 2, -PI_OVER_2}}},
+ {{{-PI_LO, -PI}, {PI_LO / 2, PI_OVER_2}},
+ {{-PI_LO, -PI}, {PI_LO / 2, PI_OVER_2}}}};
+
+ FPBits x_bits(x), y_bits(y);
+ bool x_sign = x_bits.sign().is_neg();
+ bool y_sign = y_bits.sign().is_neg();
+ x_bits.set_sign(Sign::POS);
+ y_bits.set_sign(Sign::POS);
+ uint32_t x_abs = x_bits.uintval();
+ uint32_t y_abs = y_bits.uintval();
+ uint32_t max_abs = x_abs > y_abs ? x_abs : y_abs;
+ uint32_t min_abs = x_abs <= y_abs ? x_abs : y_abs;
+
+ if (LIBC_UNLIKELY(max_abs >= 0x7f80'0000U || min_abs == 0U)) {
+ if (x_bits.is_nan() || y_bits.is_nan())
+ return FPBits::quiet_nan().get_val();
+ size_t x_except = x_abs == 0 ? 0 : (x_abs == 0x7f80'0000 ? 2 : 1);
+ size_t y_except = y_abs == 0 ? 0 : (y_abs == 0x7f80'0000 ? 2 : 1);
+
+ // Exceptional cases:
+ // EXCEPT[y_except][x_except][x_is_neg]
+ // with x_except & y_except:
+ // 0: zero
+ // 1: finite, non-zero
+ // 2: infinity
+ constexpr double EXCEPTS[3][3][2] = {
+ {{0.0, PI}, {0.0, PI}, {0.0, PI}},
+ {{PI_OVER_2, PI_OVER_2}, {0.0, 0.0}, {0.0, PI}},
+ {{PI_OVER_2, PI_OVER_2},
+ {PI_OVER_2, PI_OVER_2},
+ {PI_OVER_4, THREE_PI_OVER_4}},
+ };
+
+ double r = IS_NEG[y_sign] * EXCEPTS[y_except][x_except][x_sign];
+
+ return static_cast<float>(r);
+ }
+
+ bool recip = x_abs < y_abs;
+ double final_sign = IS_NEG[(x_sign != y_sign) != recip];
+ fputil::DoubleDouble const_term = CONST_ADJ[x_sign][y_sign][recip];
+ double num_d = static_cast<double>(FPBits(min_abs).get_val());
+ double den_d = static_cast<double>(FPBits(max_abs).get_val());
+ double q_d = num_d / den_d;
+
+ double k_d = fputil::nearest_integer(q_d * 0x1.0p4f);
+ int idx = static_cast<int>(k_d);
+ q_d = fputil::multiply_add(k_d, -0x1.0p-4, q_d);
+
+ double p = atan_eval(q_d, idx);
+ double r = final_sign *
+ fputil::multiply_add(q_d, p, const_term.hi + ATAN_COEFFS[idx][0]);
+
+ constexpr uint32_t LOWER_ERR = 4;
+ // Mask sticky bits in double precision before rounding to single precision.
+ constexpr uint32_t MASK =
+ mask_trailing_ones<uint32_t, fputil::FPBits<double>::SIG_LEN -
+ FPBits::SIG_LEN - 1>();
+ constexpr uint32_t UPPER_ERR = MASK - LOWER_ERR;
+
+ uint32_t r_bits = static_cast<uint32_t>(cpp::bit_cast<uint64_t>(r)) & MASK;
+
+ // Ziv's rounding test.
+ if (LIBC_LIKELY(r_bits > LOWER_ERR && r_bits < UPPER_ERR))
+ return static_cast<float>(r);
+
+ return atan2f_double_double(num_d, den_d, q_d, idx, k_d, final_sign,
+ const_term);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/atanf.cpp b/src/math/generic/atanf.cpp
index e0f8a1bfc2ec..9fa1a331c9c0 100644
--- a/src/math/generic/atanf.cpp
+++ b/src/math/generic/atanf.cpp
@@ -7,60 +7,114 @@
//===----------------------------------------------------------------------===//
#include "src/math/atanf.h"
-#include "math_utils.h"
+#include "inv_trigf_utils.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/math/generic/inv_trigf_utils.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, atanf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
- // x == 0.0
- if (LIBC_UNLIKELY(x == 0.0f))
- return x;
+ constexpr double FINAL_SIGN[2] = {1.0, -1.0};
+ constexpr double SIGNED_PI_OVER_2[2] = {0x1.921fb54442d18p0,
+ -0x1.921fb54442d18p0};
- FPBits xbits(x);
- Sign sign = xbits.sign();
- xbits.set_sign(Sign::POS);
+ FPBits x_bits(x);
+ Sign sign = x_bits.sign();
+ x_bits.set_sign(Sign::POS);
+ uint32_t x_abs = x_bits.uintval();
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
- if (xbits.is_inf())
- return static_cast<float>(
- opt_barrier(sign.is_neg() ? -M_MATH_PI_2 : M_MATH_PI_2));
- else
+ // x is inf or nan, |x| < 2^-4 or |x|= > 16.
+ if (LIBC_UNLIKELY(x_abs <= 0x3d80'0000U || x_abs >= 0x4180'0000U)) {
+ double x_d = static_cast<double>(x);
+ double const_term = 0.0;
+ if (LIBC_UNLIKELY(x_abs >= 0x4180'0000)) {
+ // atan(+-Inf) = +-pi/2.
+ if (x_bits.is_inf()) {
+ volatile double sign_pi_over_2 = SIGNED_PI_OVER_2[sign.is_neg()];
+ return static_cast<float>(sign_pi_over_2);
+ }
+ if (x_bits.is_nan())
+ return x;
+ // x >= 16
+ x_d = -1.0 / x_d;
+ const_term = SIGNED_PI_OVER_2[sign.is_neg()];
+ }
+ // 0 <= x < 1/16;
+ if (LIBC_UNLIKELY(x_bits.is_zero()))
return x;
- }
- // |x| == 0.06905200332403183
- if (LIBC_UNLIKELY(xbits.uintval() == 0x3d8d6b23U)) {
- if (fputil::fenv_is_round_to_nearest()) {
- // 0.06894256919622421
- FPBits br(0x3d8d31c3U);
- br.set_sign(sign);
- return br.get_val();
+ // x <= 2^-12;
+ if (LIBC_UNLIKELY(x_abs < 0x3980'0000)) {
+#if defined(LIBC_TARGET_CPU_HAS_FMA)
+ return fputil::multiply_add(x, -0x1.0p-25f, x);
+#else
+ double x_d = static_cast<double>(x);
+ return static_cast<float>(fputil::multiply_add(x_d, -0x1.0p-25, x_d));
+#endif // LIBC_TARGET_CPU_HAS_FMA
}
+ // Use Taylor polynomial:
+ // atan(x) ~ x * (1 - x^2 / 3 + x^4 / 5 - x^6 / 7 + x^8 / 9 - x^10 / 11).
+ constexpr double ATAN_TAYLOR[6] = {
+ 0x1.0000000000000p+0, -0x1.5555555555555p-2, 0x1.999999999999ap-3,
+ -0x1.2492492492492p-3, 0x1.c71c71c71c71cp-4, -0x1.745d1745d1746p-4,
+ };
+ double x2 = x_d * x_d;
+ double x4 = x2 * x2;
+ double c0 = fputil::multiply_add(x2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
+ double c1 = fputil::multiply_add(x2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
+ double c2 = fputil::multiply_add(x2, ATAN_TAYLOR[5], ATAN_TAYLOR[4]);
+ double p = fputil::polyeval(x4, c0, c1, c2);
+ double r = fputil::multiply_add(x_d, p, const_term);
+ return static_cast<float>(r);
}
- // |x| == 1.8670953512191772
- if (LIBC_UNLIKELY(xbits.uintval() == 0x3feefcfbU)) {
- int rounding_mode = fputil::quick_get_round();
- if (sign.is_neg()) {
- if (rounding_mode == FE_DOWNWARD) {
- // -1.0790828466415405
- return FPBits(0xbf8a1f63U).get_val();
- }
- } else {
- if (rounding_mode == FE_UPWARD) {
- // 1.0790828466415405
- return FPBits(0x3f8a1f63U).get_val();
- }
+ // Range reduction steps:
+ // 1) atan(x) = sign(x) * atan(|x|)
+ // 2) If |x| > 1, atan(|x|) = pi/2 - atan(1/|x|)
+ // 3) For 1/16 < x <= 1, we find k such that: |x - k/16| <= 1/32.
+ // 4) Then we use polynomial approximation:
+ // atan(x) ~ atan((k/16) + (x - (k/16)) * Q(x - k/16)
+ // = P(x - k/16)
+ double x_d, const_term, final_sign;
+ int idx;
+
+ if (x_abs > 0x3f80'0000U) {
+ // |x| > 1, we need to invert x, so we will perform range reduction in
+ // double precision.
+ x_d = 1.0 / static_cast<double>(x_bits.get_val());
+ double k_d = fputil::nearest_integer(x_d * 0x1.0p4);
+ x_d = fputil::multiply_add(k_d, -0x1.0p-4, x_d);
+ idx = static_cast<int>(k_d);
+ final_sign = FINAL_SIGN[sign.is_pos()];
+ // Adjust constant term of the polynomial by +- pi/2.
+ const_term = fputil::multiply_add(final_sign, ATAN_COEFFS[idx][0],
+ SIGNED_PI_OVER_2[sign.is_neg()]);
+ } else {
+ // Exceptional value:
+ if (LIBC_UNLIKELY(x_abs == 0x3d8d'6b23U)) { // |x| = 0x1.1ad646p-4
+ return sign.is_pos() ? fputil::round_result_slightly_down(0x1.1a6386p-4f)
+ : fputil::round_result_slightly_up(-0x1.1a6386p-4f);
}
+ // Perform range reduction in single precision.
+ float x_f = x_bits.get_val();
+ float k_f = fputil::nearest_integer(x_f * 0x1.0p4f);
+ x_f = fputil::multiply_add(k_f, -0x1.0p-4f, x_f);
+ x_d = static_cast<double>(x_f);
+ idx = static_cast<int>(k_f);
+ final_sign = FINAL_SIGN[sign.is_neg()];
+ const_term = final_sign * ATAN_COEFFS[idx][0];
}
- return static_cast<float>(atan_eval(x));
+ double p = atan_eval(x_d, idx);
+ double r = fputil::multiply_add(final_sign * x_d, p, const_term);
+
+ return static_cast<float>(r);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/atanhf.cpp b/src/math/generic/atanhf.cpp
index fe2c36494a72..97fd1b233600 100644
--- a/src/math/generic/atanhf.cpp
+++ b/src/math/generic/atanhf.cpp
@@ -15,7 +15,7 @@ namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, atanhf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
Sign sign = xbits.sign();
uint32_t x_abs = xbits.abs().uintval();
diff --git a/src/math/generic/canonicalize.cpp b/src/math/generic/canonicalize.cpp
new file mode 100644
index 000000000000..f38ca01e157f
--- /dev/null
+++ b/src/math/generic/canonicalize.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of canonicalize 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/canonicalize.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
+ return fputil::canonicalize(*cx, *x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/canonicalizef.cpp b/src/math/generic/canonicalizef.cpp
new file mode 100644
index 000000000000..dce601de1491
--- /dev/null
+++ b/src/math/generic/canonicalizef.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of canonicalizef 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/canonicalizef.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
+ return fputil::canonicalize(*cx, *x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/canonicalizef128.cpp b/src/math/generic/canonicalizef128.cpp
new file mode 100644
index 000000000000..0078b478238c
--- /dev/null
+++ b/src/math/generic/canonicalizef128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of canonicalizef128 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/canonicalizef128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
+ return fputil::canonicalize(*cx, *x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/canonicalizel.cpp b/src/math/generic/canonicalizel.cpp
new file mode 100644
index 000000000000..5310a316acdd
--- /dev/null
+++ b/src/math/generic/canonicalizel.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of canonicalizel 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/canonicalizel.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizel,
+ (long double *cx, const long double *x)) {
+ return fputil::canonicalize(*cx, *x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ceilf128.cpp b/src/math/generic/ceilf128.cpp
new file mode 100644
index 000000000000..af980429f87d
--- /dev/null
+++ b/src/math/generic/ceilf128.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of ceilf128 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/ceilf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, ceilf128, (float128 x)) { return fputil::ceil(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/cosf.cpp b/src/math/generic/cosf.cpp
index d59304933d60..180a44e947ea 100644
--- a/src/math/generic/cosf.cpp
+++ b/src/math/generic/cosf.cpp
@@ -42,7 +42,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
xbits.set_sign(Sign::POS);
diff --git a/src/math/generic/coshf.cpp b/src/math/generic/coshf.cpp
index a618056a64dc..a8ea324c9505 100644
--- a/src/math/generic/coshf.cpp
+++ b/src/math/generic/coshf.cpp
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, coshf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
xbits.set_sign(Sign::POS);
x = xbits.get_val();
diff --git a/src/math/generic/exp.cpp b/src/math/generic/exp.cpp
index f23170f8ed42..3d060bcbd3be 100644
--- a/src/math/generic/exp.cpp
+++ b/src/math/generic/exp.cpp
@@ -21,6 +21,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include <errno.h>
@@ -30,7 +31,8 @@ namespace LIBC_NAMESPACE {
using fputil::DoubleDouble;
using fputil::TripleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
// log2(e)
constexpr double LOG2_E = 0x1.71547652b82fep+0;
@@ -97,21 +99,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// For |dx| < 2^-13 + 2^-30:
// | output - exp(dx) | < 2^-126.
Float128 poly_approx_f128(const Float128 &dx) {
- using MType = typename Float128::MantissaType;
-
constexpr Float128 COEFFS_128[]{
- {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
- {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
- {Sign::POS, -128, MType({0, 0x8000000000000000})}, // 0.5
- {Sign::POS, -130, MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/6
- {Sign::POS, -132,
- MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/24
- {Sign::POS, -134,
- MType({0x8888888888888889, 0x8888888888888888})}, // 1/120
- {Sign::POS, -137,
- MType({0x60b60b60b60b60b6, 0xb60b60b60b60b60b})}, // 1/720
- {Sign::POS, -140,
- MType({0x00d00d00d00d00d0, 0xd00d00d00d00d00d})}, // 1/5040
+ {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+ {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+ {Sign::POS, -128, 0x80000000'00000000'00000000'00000000_u128}, // 0.5
+ {Sign::POS, -130, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/6
+ {Sign::POS, -132, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/24
+ {Sign::POS, -134, 0x88888888'88888888'88888888'88888889_u128}, // 1/120
+ {Sign::POS, -137, 0xb60b60b6'0b60b60b'60b60b60'b60b60b6_u128}, // 1/720
+ {Sign::POS, -140, 0xd00d00d0'0d00d00d'00d00d00'd00d00d0_u128}, // 1/5040
};
Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/src/math/generic/exp10.cpp b/src/math/generic/exp10.cpp
index 6b40f5561845..a4ae41407112 100644
--- a/src/math/generic/exp10.cpp
+++ b/src/math/generic/exp10.cpp
@@ -21,6 +21,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include <errno.h>
@@ -30,7 +31,8 @@ namespace LIBC_NAMESPACE {
using fputil::DoubleDouble;
using fputil::TripleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
// log2(10)
constexpr double LOG2_10 = 0x1.a934f0979a371p+1;
@@ -99,17 +101,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// For |dx| < 2^-14:
// | output - 10^dx | < 1.5 * 2^-124.
Float128 poly_approx_f128(const Float128 &dx) {
- using MType = typename Float128::MantissaType;
-
constexpr Float128 COEFFS_128[]{
- {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
- {Sign::POS, -126, MType({0xea56d62b82d30a2d, 0x935d8dddaaa8ac16})},
- {Sign::POS, -126, MType({0x80a99ce75f4d5bdb, 0xa9a92639e753443a})},
- {Sign::POS, -126, MType({0x6a4f9d7dbf6c9635, 0x82382c8ef1652304})},
- {Sign::POS, -124, MType({0x345787019216c7af, 0x12bd7609fd98c44c})},
- {Sign::POS, -127, MType({0xcc41ed7e0d27aee5, 0x450a7ff47535d889})},
- {Sign::POS, -130, MType({0x8326bb91a6e7601d, 0xd3f6b844702d636b})},
- {Sign::POS, -130, MType({0xfa7b46df314112a9, 0x45b937f0d05bb1cd})},
+ {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+ {Sign::POS, -126, 0x935d8ddd'aaa8ac16'ea56d62b'82d30a2d_u128},
+ {Sign::POS, -126, 0xa9a92639'e753443a'80a99ce7'5f4d5bdb_u128},
+ {Sign::POS, -126, 0x82382c8e'f1652304'6a4f9d7d'bf6c9635_u128},
+ {Sign::POS, -124, 0x12bd7609'fd98c44c'34578701'9216c7af_u128},
+ {Sign::POS, -127, 0x450a7ff4'7535d889'cc41ed7e'0d27aee5_u128},
+ {Sign::POS, -130, 0xd3f6b844'702d636b'8326bb91'a6e7601d_u128},
+ {Sign::POS, -130, 0x45b937f0'd05bb1cd'fa7b46df'314112a9_u128},
};
Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/src/math/generic/exp2.cpp b/src/math/generic/exp2.cpp
index 01e66d1ae00f..1a2fa3feb83e 100644
--- a/src/math/generic/exp2.cpp
+++ b/src/math/generic/exp2.cpp
@@ -21,6 +21,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include <errno.h>
@@ -30,7 +31,8 @@ namespace LIBC_NAMESPACE {
using fputil::DoubleDouble;
using fputil::TripleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
// Error bounds:
// Errors when using double precision.
@@ -88,17 +90,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// For |dx| < 2^-13 + 2^-30:
// | output - exp(dx) | < 2^-126.
Float128 poly_approx_f128(const Float128 &dx) {
- using MType = typename Float128::MantissaType;
-
constexpr Float128 COEFFS_128[]{
- {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
- {Sign::POS, -128, MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab})},
- {Sign::POS, -128, MType({0xde2d60dd9c9a1d9f, 0x3d7f7bff058b1d50})},
- {Sign::POS, -132, MType({0x9d3b15d9e7fb6897, 0xe35846b82505fc59})},
- {Sign::POS, -134, MType({0x184462f6bcd2b9e7, 0x9d955b7dd273b94e})},
- {Sign::POS, -137, MType({0x39ea1bb964c51a89, 0xaec3ff3c53398883})},
- {Sign::POS, -138, MType({0x842c53418fa8ae61, 0x2861225f345c396a})},
- {Sign::POS, -144, MType({0x7abeb5abd5ad2079, 0xffe5fe2d109a319d})},
+ {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+ {Sign::POS, -128, 0xb17217f7'd1cf79ab'c9e3b398'03f2f6af_u128},
+ {Sign::POS, -128, 0x3d7f7bff'058b1d50'de2d60dd'9c9a1d9f_u128},
+ {Sign::POS, -132, 0xe35846b8'2505fc59'9d3b15d9'e7fb6897_u128},
+ {Sign::POS, -134, 0x9d955b7d'd273b94e'184462f6'bcd2b9e7_u128},
+ {Sign::POS, -137, 0xaec3ff3c'53398883'39ea1bb9'64c51a89_u128},
+ {Sign::POS, -138, 0x2861225f'345c396a'842c5341'8fa8ae61_u128},
+ {Sign::POS, -144, 0xffe5fe2d'109a319d'7abeb5ab'd5ad2079_u128},
};
Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/src/math/generic/exp2m1f.cpp b/src/math/generic/exp2m1f.cpp
new file mode 100644
index 000000000000..c60930dd782e
--- /dev/null
+++ b/src/math/generic/exp2m1f.cpp
@@ -0,0 +1,183 @@
+//===-- Implementation of exp2m1f 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/exp2m1f.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/errno/libc_errno.h"
+
+#include "explogxf.h"
+
+namespace LIBC_NAMESPACE {
+
+static constexpr size_t N_EXCEPTS_LO = 8;
+
+static constexpr fputil::ExceptValues<float, N_EXCEPTS_LO> EXP2M1F_EXCEPTS_LO =
+ {{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.36dc8ep-36, exp2m1f(x) = 0x1.aef212p-37 (RZ)
+ {0x2d9b'6e47U, 0x2d57'7909U, 1U, 0U, 0U},
+ // x = 0x1.224936p-19, exp2m1f(x) = 0x1.926c0ep-20 (RZ)
+ {0x3611'249bU, 0x35c9'3607U, 1U, 0U, 1U},
+ // x = 0x1.d16d2p-20, exp2m1f(x) = 0x1.429becp-20 (RZ)
+ {0x35e8'b690U, 0x35a1'4df6U, 1U, 0U, 1U},
+ // x = 0x1.17949ep-14, exp2m1f(x) = 0x1.8397p-15 (RZ)
+ {0x388b'ca4fU, 0x3841'cb80U, 1U, 0U, 1U},
+ // x = -0x1.9c3e1ep-38, exp2m1f(x) = -0x1.1dbeacp-38 (RZ)
+ {0xacce'1f0fU, 0xac8e'df56U, 0U, 1U, 0U},
+ // x = -0x1.4d89b4p-32, exp2m1f(x) = -0x1.ce61b6p-33 (RZ)
+ {0xafa6'c4daU, 0xaf67'30dbU, 0U, 1U, 1U},
+ // x = -0x1.a6eac4p-10, exp2m1f(x) = -0x1.24fadap-10 (RZ)
+ {0xbad3'7562U, 0xba92'7d6dU, 0U, 1U, 1U},
+ // x = -0x1.e7526ep-6, exp2m1f(x) = -0x1.4e53dep-6 (RZ)
+ {0xbcf3'a937U, 0xbca7'29efU, 0U, 1U, 1U},
+ }};
+
+static constexpr size_t N_EXCEPTS_HI = 3;
+
+static constexpr fputil::ExceptValues<float, N_EXCEPTS_HI> EXP2M1F_EXCEPTS_HI =
+ {{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.16a972p-1, exp2m1f(x) = 0x1.d545b2p-2 (RZ)
+ {0x3f0b'54b9U, 0x3eea'a2d9U, 1U, 0U, 0U},
+ // x = -0x1.9f12acp-5, exp2m1f(x) = -0x1.1ab68cp-5 (RZ)
+ {0xbd4f'8956U, 0xbd0d'5b46U, 0U, 1U, 0U},
+ // x = -0x1.de7b9cp-5, exp2m1f(x) = -0x1.4508f4p-5 (RZ)
+ {0xbd6f'3dceU, 0xbd22'847aU, 0U, 1U, 1U},
+ }};
+
+LLVM_LIBC_FUNCTION(float, exp2m1f, (float x)) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= 128, or x is nan, or |x| <= 2^-5
+ if (LIBC_UNLIKELY(x_abs >= 0x4300'0000U || x_abs <= 0x3d00'0000U)) {
+ // |x| <= 2^-5
+ if (x_abs <= 0x3d00'0000U) {
+ if (auto r = EXP2M1F_EXCEPTS_LO.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+
+ // Minimax polynomial generated by Sollya with:
+ // > display = hexadecimal;
+ // > fpminimax((2^x - 1)/x, 5, [|D...|], [-2^-5, 2^-5]);
+ constexpr double COEFFS[] = {
+ 0x1.62e42fefa39f3p-1, 0x1.ebfbdff82c57bp-3, 0x1.c6b08d6f2d7aap-5,
+ 0x1.3b2ab6fc92f5dp-7, 0x1.5d897cfe27125p-10, 0x1.43090e61e6af1p-13};
+ double xd = x;
+ double xsq = xd * xd;
+ double c0 = fputil::multiply_add(xd, COEFFS[1], COEFFS[0]);
+ double c1 = fputil::multiply_add(xd, COEFFS[3], COEFFS[2]);
+ double c2 = fputil::multiply_add(xd, COEFFS[5], COEFFS[4]);
+ double p = fputil::polyeval(xsq, c0, c1, c2);
+ return static_cast<float>(p * xd);
+ }
+
+ // x >= 128, or x is nan
+ if (xbits.is_pos()) {
+ if (xbits.is_finite()) {
+ int rounding = fputil::quick_get_round();
+ if (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);
+ }
+
+ // x >= 128 and 2^x - 1 rounds to +inf, or x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ }
+
+ if (LIBC_UNLIKELY(x <= -25.0f)) {
+ // 2^(-inf) - 1 = -1
+ if (xbits.is_inf())
+ return -1.0f;
+ // 2^nan - 1 = nan
+ if (xbits.is_nan())
+ return x;
+
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_UPWARD || rounding == FE_TOWARDZERO)
+ return -0x1.ffff'fep-1f; // -1.0f + 0x1.0p-24f
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ return -1.0f;
+ }
+
+ if (auto r = EXP2M1F_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+
+ // For -25 < x < 128, to compute 2^x, we perform the following range
+ // reduction: find hi, mid, lo such that:
+ // x = hi + mid + lo, in which:
+ // hi is an integer,
+ // 0 <= mid * 2^5 < 32 is an integer,
+ // -2^(-6) <= lo <= 2^(-6).
+ // In particular,
+ // hi + mid = round(x * 2^5) * 2^(-5).
+ // Then,
+ // 2^x = 2^(hi + mid + lo) = 2^hi * 2^mid * 2^lo.
+ // 2^mid is stored in the lookup table of 32 elements.
+ // 2^lo is computed using a degree-4 minimax polynomial generated by Sollya.
+ // We perform 2^hi * 2^mid by simply add hi to the exponent field of 2^mid.
+
+ // kf = (hi + mid) * 2^5 = round(x * 2^5)
+ float kf;
+ int k;
+#ifdef LIBC_TARGET_CPU_HAS_NEAREST_INT
+ kf = fputil::nearest_integer(x * 32.0f);
+ k = static_cast<int>(kf);
+#else
+ constexpr float HALF[2] = {0.5f, -0.5f};
+ k = static_cast<int>(fputil::multiply_add(x, 32.0f, HALF[x < 0.0f]));
+ kf = static_cast<float>(k);
+#endif // LIBC_TARGET_CPU_HAS_NEAREST_INT
+
+ // lo = x - (hi + mid) = x - kf * 2^(-5)
+ double lo = fputil::multiply_add(-0x1.0p-5f, kf, x);
+
+ // hi = floor(kf * 2^(-4))
+ // exp2_hi = shift hi to the exponent field of double precision.
+ int64_t exp2_hi =
+ static_cast<int64_t>(static_cast<uint64_t>(k >> ExpBase::MID_BITS)
+ << fputil::FPBits<double>::FRACTION_LEN);
+ // mh = 2^hi * 2^mid
+ // mh_bits = bit field of mh
+ int64_t mh_bits = ExpBase::EXP_2_MID[k & ExpBase::MID_MASK] + exp2_hi;
+ double mh = fputil::FPBits<double>(static_cast<uint64_t>(mh_bits)).get_val();
+
+ // Degree-4 polynomial approximating (2^x - 1)/x generated by Sollya with:
+ // > display = hexadecimal;
+ // > fpminimax((2^x - 1)/x, 4, [|D...|], [-2^-6, 2^-6]);
+ constexpr double COEFFS[5] = {0x1.62e42fefa39efp-1, 0x1.ebfbdff8131c4p-3,
+ 0x1.c6b08d7061695p-5, 0x1.3b2b1bee74b2ap-7,
+ 0x1.5d88091198529p-10};
+ double lo_sq = lo * lo;
+ double c1 = fputil::multiply_add(lo, COEFFS[0], 1.0);
+ double c2 = fputil::multiply_add(lo, COEFFS[2], COEFFS[1]);
+ double c3 = fputil::multiply_add(lo, COEFFS[4], COEFFS[3]);
+ double exp2_lo = fputil::polyeval(lo_sq, c1, c2, c3);
+ // 2^x - 1 = 2^(hi + mid + lo) - 1
+ // = 2^(hi + mid) * 2^lo - 1
+ // ~ mh * (1 + lo * P(lo)) - 1
+ // = mh * exp2_lo - 1
+ return static_cast<float>(fputil::multiply_add(exp2_lo, mh, -1.0));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/exp_utils.h b/src/math/generic/exp_utils.h
index 49d9a8192d34..405678c356f3 100644
--- a/src/math/generic/exp_utils.h
+++ b/src/math/generic/exp_utils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_EXP_UTILS_H
-#define LLVM_LIBC_SRC_MATH_EXP_UTILS_H
+#ifndef LLVM_LIBC_SRC_MATH_GENERIC_EXP_UTILS_H
+#define LLVM_LIBC_SRC_MATH_GENERIC_EXP_UTILS_H
#include <stdint.h>
@@ -30,4 +30,4 @@ extern const Exp2fDataTable exp2f_data;
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_MATH_EXP_UTILS_H
+#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXP_UTILS_H
diff --git a/src/math/generic/expm1.cpp b/src/math/generic/expm1.cpp
index c1fb80309d7b..574c4b9aaf39 100644
--- a/src/math/generic/expm1.cpp
+++ b/src/math/generic/expm1.cpp
@@ -22,6 +22,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include <errno.h>
@@ -38,7 +39,8 @@ namespace LIBC_NAMESPACE {
using fputil::DoubleDouble;
using fputil::TripleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
// log2(e)
constexpr double LOG2_E = 0x1.71547652b82fep+0;
@@ -107,20 +109,14 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// For |dx| < 2^-13 + 2^-30:
// | output - exp(dx) | < 2^-126.
Float128 poly_approx_f128(const Float128 &dx) {
- using MType = typename Float128::MantissaType;
-
constexpr Float128 COEFFS_128[]{
- {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
- {Sign::POS, -128, MType({0, 0x8000000000000000})}, // 0.5
- {Sign::POS, -130, MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/6
- {Sign::POS, -132,
- MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/24
- {Sign::POS, -134,
- MType({0x8888888888888889, 0x8888888888888888})}, // 1/120
- {Sign::POS, -137,
- MType({0x60b60b60b60b60b6, 0xb60b60b60b60b60b})}, // 1/720
- {Sign::POS, -140,
- MType({0x00d00d00d00d00d0, 0xd00d00d00d00d00d})}, // 1/5040
+ {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+ {Sign::POS, -128, 0x80000000'00000000'00000000'00000000_u128}, // 0.5
+ {Sign::POS, -130, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/6
+ {Sign::POS, -132, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/24
+ {Sign::POS, -134, 0x88888888'88888888'88888888'88888889_u128}, // 1/120
+ {Sign::POS, -137, 0xb60b60b6'0b60b60b'60b60b60'b60b60b6_u128}, // 1/720
+ {Sign::POS, -140, 0xd00d00d0'0d00d00d'00d00d00'd00d00d0_u128}, // 1/5040
};
Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
@@ -146,7 +142,6 @@ std::ostream &operator<<(std::ostream &OS, const DoubleDouble &r) {
// TODO(lntue): investigate triple-double precision implementation for this
// step.
Float128 expm1_f128(double x, double kd, int idx1, int idx2) {
- using MType = typename Float128::MantissaType;
// Recalculate dx:
double t1 = fputil::multiply_add(kd, MLOG_2_EXP2_M12_HI, x); // exact
@@ -170,7 +165,8 @@ Float128 expm1_f128(double x, double kd, int idx1, int idx2) {
Float128 exp_mid = fputil::quick_mul(exp_mid1, exp_mid2);
int hi = static_cast<int>(kd) >> 12;
- Float128 minus_one{Sign::NEG, -127 - hi, MType({0, 0x8000000000000000})};
+ Float128 minus_one{Sign::NEG, -127 - hi,
+ 0x80000000'00000000'00000000'00000000_u128};
Float128 exp_mid_m1 = fputil::quick_add(exp_mid, minus_one);
@@ -280,7 +276,7 @@ double set_exceptional(double x) {
LLVM_LIBC_FUNCTION(double, expm1, (double x)) {
using FPBits = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
bool x_is_neg = xbits.is_neg();
diff --git a/src/math/generic/fdimf128.cpp b/src/math/generic/fdimf128.cpp
new file mode 100644
index 000000000000..a3ea9e591610
--- /dev/null
+++ b/src/math/generic/fdimf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fdimf128 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/fdimf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fdimf128, (float128 x, float128 y)) {
+ return fputil::fdim(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/floorf128.cpp b/src/math/generic/floorf128.cpp
new file mode 100644
index 000000000000..22a8eacb45dd
--- /dev/null
+++ b/src/math/generic/floorf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of floorf128 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/floorf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, floorf128, (float128 x)) {
+ return fputil::floor(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum.cpp b/src/math/generic/fmaximum.cpp
new file mode 100644
index 000000000000..ac9593b325d4
--- /dev/null
+++ b/src/math/generic/fmaximum.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum 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.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum, (double x, double y)) {
+ return fputil::fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_mag.cpp b/src/math/generic/fmaximum_mag.cpp
new file mode 100644
index 000000000000..0deb0c2835f9
--- /dev/null
+++ b/src/math/generic/fmaximum_mag.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_mag 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.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum_mag, (double x, double y)) {
+ return fputil::fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_mag_num.cpp b/src/math/generic/fmaximum_mag_num.cpp
new file mode 100644
index 000000000000..d0b1096b88bc
--- /dev/null
+++ b/src/math/generic/fmaximum_mag_num.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_mag_num 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_num.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum_mag_num, (double x, double y)) {
+ return fputil::fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_mag_numf.cpp b/src/math/generic/fmaximum_mag_numf.cpp
new file mode 100644
index 000000000000..672d3fd3b263
--- /dev/null
+++ b/src/math/generic/fmaximum_mag_numf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_mag_numf 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_numf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaximum_mag_numf, (float x, float y)) {
+ return fputil::fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_mag_numf128.cpp b/src/math/generic/fmaximum_mag_numf128.cpp
new file mode 100644
index 000000000000..e7d13f13a098
--- /dev/null
+++ b/src/math/generic/fmaximum_mag_numf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_mag_numf128 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_numf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fmaximum_mag_numf128, (float128 x, float128 y)) {
+ return fputil::fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_mag_numl.cpp b/src/math/generic/fmaximum_mag_numl.cpp
new file mode 100644
index 000000000000..a8499ca473b3
--- /dev/null
+++ b/src/math/generic/fmaximum_mag_numl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fmaximum_mag_numl 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_numl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fmaximum_mag_numl,
+ (long double x, long double y)) {
+ return fputil::fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_magf.cpp b/src/math/generic/fmaximum_magf.cpp
new file mode 100644
index 000000000000..380aca05a525
--- /dev/null
+++ b/src/math/generic/fmaximum_magf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_magf 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_magf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaximum_magf, (float x, float y)) {
+ return fputil::fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_magf128.cpp b/src/math/generic/fmaximum_magf128.cpp
new file mode 100644
index 000000000000..301938fb7ffd
--- /dev/null
+++ b/src/math/generic/fmaximum_magf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_magf128 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_magf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fmaximum_magf128, (float128 x, float128 y)) {
+ return fputil::fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_magl.cpp b/src/math/generic/fmaximum_magl.cpp
new file mode 100644
index 000000000000..283a11eda9aa
--- /dev/null
+++ b/src/math/generic/fmaximum_magl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_magl 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_magl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fmaximum_magl, (long double x, long double y)) {
+ return fputil::fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_num.cpp b/src/math/generic/fmaximum_num.cpp
new file mode 100644
index 000000000000..23553dbcae7e
--- /dev/null
+++ b/src/math/generic/fmaximum_num.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_num 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_num.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum_num, (double x, double y)) {
+ return fputil::fmaximum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_numf.cpp b/src/math/generic/fmaximum_numf.cpp
new file mode 100644
index 000000000000..f946ff43f543
--- /dev/null
+++ b/src/math/generic/fmaximum_numf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_numf 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_numf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaximum_numf, (float x, float y)) {
+ return fputil::fmaximum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_numf128.cpp b/src/math/generic/fmaximum_numf128.cpp
new file mode 100644
index 000000000000..f33a5e195bf2
--- /dev/null
+++ b/src/math/generic/fmaximum_numf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_numf128 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_numf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fmaximum_numf128, (float128 x, float128 y)) {
+ return fputil::fmaximum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximum_numl.cpp b/src/math/generic/fmaximum_numl.cpp
new file mode 100644
index 000000000000..503fc41409f6
--- /dev/null
+++ b/src/math/generic/fmaximum_numl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximum_numl 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_numl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fmaximum_numl, (long double x, long double y)) {
+ return fputil::fmaximum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximumf.cpp b/src/math/generic/fmaximumf.cpp
new file mode 100644
index 000000000000..3b2a60931bf6
--- /dev/null
+++ b/src/math/generic/fmaximumf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximumf 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/fmaximumf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaximumf, (float x, float y)) {
+ return fputil::fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximumf128.cpp b/src/math/generic/fmaximumf128.cpp
new file mode 100644
index 000000000000..0099c913b052
--- /dev/null
+++ b/src/math/generic/fmaximumf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximumf128 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/fmaximumf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fmaximumf128, (float128 x, float128 y)) {
+ return fputil::fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmaximuml.cpp b/src/math/generic/fmaximuml.cpp
new file mode 100644
index 000000000000..ecd698300458
--- /dev/null
+++ b/src/math/generic/fmaximuml.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fmaximuml 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/fmaximuml.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fmaximuml, (long double x, long double y)) {
+ return fputil::fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum.cpp b/src/math/generic/fminimum.cpp
new file mode 100644
index 000000000000..28b257d950f4
--- /dev/null
+++ b/src/math/generic/fminimum.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum 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.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fminimum, (double x, double y)) {
+ return fputil::fminimum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_mag.cpp b/src/math/generic/fminimum_mag.cpp
new file mode 100644
index 000000000000..6af99570e1ea
--- /dev/null
+++ b/src/math/generic/fminimum_mag.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_mag 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.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fminimum_mag, (double x, double y)) {
+ return fputil::fminimum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_mag_num.cpp b/src/math/generic/fminimum_mag_num.cpp
new file mode 100644
index 000000000000..fc5431ae2799
--- /dev/null
+++ b/src/math/generic/fminimum_mag_num.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_mag_num 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_num.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fminimum_mag_num, (double x, double y)) {
+ return fputil::fminimum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_mag_numf.cpp b/src/math/generic/fminimum_mag_numf.cpp
new file mode 100644
index 000000000000..71179a6f03c2
--- /dev/null
+++ b/src/math/generic/fminimum_mag_numf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_mag_numf 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_numf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fminimum_mag_numf, (float x, float y)) {
+ return fputil::fminimum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_mag_numf128.cpp b/src/math/generic/fminimum_mag_numf128.cpp
new file mode 100644
index 000000000000..109ce7e4e011
--- /dev/null
+++ b/src/math/generic/fminimum_mag_numf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_mag_numf128 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_numf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fminimum_mag_numf128, (float128 x, float128 y)) {
+ return fputil::fminimum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_mag_numl.cpp b/src/math/generic/fminimum_mag_numl.cpp
new file mode 100644
index 000000000000..c97ce6ead042
--- /dev/null
+++ b/src/math/generic/fminimum_mag_numl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fminimum_mag_numl 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_numl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fminimum_mag_numl,
+ (long double x, long double y)) {
+ return fputil::fminimum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_magf.cpp b/src/math/generic/fminimum_magf.cpp
new file mode 100644
index 000000000000..834f6a4a9710
--- /dev/null
+++ b/src/math/generic/fminimum_magf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_magf 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_magf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fminimum_magf, (float x, float y)) {
+ return fputil::fminimum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_magf128.cpp b/src/math/generic/fminimum_magf128.cpp
new file mode 100644
index 000000000000..2828e28bb0a4
--- /dev/null
+++ b/src/math/generic/fminimum_magf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_magf128 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_magf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fminimum_magf128, (float128 x, float128 y)) {
+ return fputil::fminimum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_magl.cpp b/src/math/generic/fminimum_magl.cpp
new file mode 100644
index 000000000000..50e328fd92d1
--- /dev/null
+++ b/src/math/generic/fminimum_magl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_magl 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_magl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fminimum_magl, (long double x, long double y)) {
+ return fputil::fminimum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_num.cpp b/src/math/generic/fminimum_num.cpp
new file mode 100644
index 000000000000..e89c7f5acf9b
--- /dev/null
+++ b/src/math/generic/fminimum_num.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_num 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_num.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fminimum_num, (double x, double y)) {
+ return fputil::fminimum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_numf.cpp b/src/math/generic/fminimum_numf.cpp
new file mode 100644
index 000000000000..c37c8bd423a1
--- /dev/null
+++ b/src/math/generic/fminimum_numf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_numf 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_numf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fminimum_numf, (float x, float y)) {
+ return fputil::fminimum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_numf128.cpp b/src/math/generic/fminimum_numf128.cpp
new file mode 100644
index 000000000000..6b1f77bb447c
--- /dev/null
+++ b/src/math/generic/fminimum_numf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_numf128 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_numf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fminimum_numf128, (float128 x, float128 y)) {
+ return fputil::fminimum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimum_numl.cpp b/src/math/generic/fminimum_numl.cpp
new file mode 100644
index 000000000000..22045f83f2a7
--- /dev/null
+++ b/src/math/generic/fminimum_numl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimum_numl 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_numl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fminimum_numl, (long double x, long double y)) {
+ return fputil::fminimum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimumf.cpp b/src/math/generic/fminimumf.cpp
new file mode 100644
index 000000000000..c937fb0ea01d
--- /dev/null
+++ b/src/math/generic/fminimumf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimumf 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/fminimumf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fminimumf, (float x, float y)) {
+ return fputil::fminimum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimumf128.cpp b/src/math/generic/fminimumf128.cpp
new file mode 100644
index 000000000000..24e02b8ff537
--- /dev/null
+++ b/src/math/generic/fminimumf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimumf128 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/fminimumf128.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fminimumf128, (float128 x, float128 y)) {
+ return fputil::fminimum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fminimuml.cpp b/src/math/generic/fminimuml.cpp
new file mode 100644
index 000000000000..43319503661a
--- /dev/null
+++ b/src/math/generic/fminimuml.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fminimuml 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/fminimuml.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fminimuml, (long double x, long double y)) {
+ return fputil::fminimum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmodf.cpp b/src/math/generic/fmodf.cpp
index 7a29ff1f18d3..9a9e46e29b46 100644
--- a/src/math/generic/fmodf.cpp
+++ b/src/math/generic/fmodf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, fmodf, (float x, float y)) {
- return fputil::generic::FMod<float>::eval(x, y);
+ return fputil::generic::FMod<float, uint64_t>::eval(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmodf128.cpp b/src/math/generic/fmodf128.cpp
new file mode 100644
index 000000000000..08a379702d88
--- /dev/null
+++ b/src/math/generic/fmodf128.cpp
@@ -0,0 +1,19 @@
+//===-- Single-precision fmodf128 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/fmodf128.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fmodf128, (float128 x, float128 y)) {
+ return fputil::generic::FMod<float128>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fmodl.cpp b/src/math/generic/fmodl.cpp
new file mode 100644
index 000000000000..23a370289055
--- /dev/null
+++ b/src/math/generic/fmodl.cpp
@@ -0,0 +1,19 @@
+//===-- Single-precision fmodl 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/fmodl.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fmodl, (long double x, long double y)) {
+ return fputil::generic::FMod<long double>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/frexpf128.cpp b/src/math/generic/frexpf128.cpp
new file mode 100644
index 000000000000..b50f37d2dab4
--- /dev/null
+++ b/src/math/generic/frexpf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of frexpf128 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/frexpf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, frexpf128, (float128 x, int *exp)) {
+ return fputil::frexp(x, *exp);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfp.cpp b/src/math/generic/fromfp.cpp
new file mode 100644
index 000000000000..ba3f0a133cbc
--- /dev/null
+++ b/src/math/generic/fromfp.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fromfp 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/fromfp.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fromfp, (double x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpf.cpp b/src/math/generic/fromfpf.cpp
new file mode 100644
index 000000000000..fd058a13201c
--- /dev/null
+++ b/src/math/generic/fromfpf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fromfpf 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/fromfpf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fromfpf, (float x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpf128.cpp b/src/math/generic/fromfpf128.cpp
new file mode 100644
index 000000000000..440a5da75693
--- /dev/null
+++ b/src/math/generic/fromfpf128.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpf128 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/fromfpf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fromfpf128,
+ (float128 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpl.cpp b/src/math/generic/fromfpl.cpp
new file mode 100644
index 000000000000..ee3abeaf98f8
--- /dev/null
+++ b/src/math/generic/fromfpl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpl 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/fromfpl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fromfpl,
+ (long double x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpx.cpp b/src/math/generic/fromfpx.cpp
new file mode 100644
index 000000000000..b9e7e4a7aa12
--- /dev/null
+++ b/src/math/generic/fromfpx.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fromfpx 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/fromfpx.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fromfpx, (double x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpxf.cpp b/src/math/generic/fromfpxf.cpp
new file mode 100644
index 000000000000..1473499244d3
--- /dev/null
+++ b/src/math/generic/fromfpxf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fromfpxf 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/fromfpxf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fromfpxf, (float x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpxf128.cpp b/src/math/generic/fromfpxf128.cpp
new file mode 100644
index 000000000000..5d930d22ae5e
--- /dev/null
+++ b/src/math/generic/fromfpxf128.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpxf128 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/fromfpxf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, fromfpxf128,
+ (float128 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/fromfpxl.cpp b/src/math/generic/fromfpxl.cpp
new file mode 100644
index 000000000000..c3db055246f2
--- /dev/null
+++ b/src/math/generic/fromfpxl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpxl 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/fromfpxl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, fromfpxl,
+ (long double x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/hypotf.cpp b/src/math/generic/hypotf.cpp
index 614aa399fcc2..ffbf706aefaf 100644
--- a/src/math/generic/hypotf.cpp
+++ b/src/math/generic/hypotf.cpp
@@ -48,8 +48,8 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
// Correct rounding.
double r_sq = result.get_val() * result.get_val();
double diff = sum_sq - r_sq;
- constexpr uint64_t mask = 0x0000'0000'3FFF'FFFFULL;
- uint64_t lrs = result.uintval() & mask;
+ constexpr uint64_t MASK = 0x0000'0000'3FFF'FFFFULL;
+ uint64_t lrs = result.uintval() & MASK;
if (lrs == 0x0000'0000'1000'0000ULL && err < diff) {
result.set_uintval(result.uintval() | 1ULL);
diff --git a/src/math/generic/ilogb.cpp b/src/math/generic/ilogb.cpp
index 4e5f7d9642b4..7e4f66970c5d 100644
--- a/src/math/generic/ilogb.cpp
+++ b/src/math/generic/ilogb.cpp
@@ -12,6 +12,6 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::intlogb<int>(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ilogbf.cpp b/src/math/generic/ilogbf.cpp
index ca15879bc25f..422788cec9e0 100644
--- a/src/math/generic/ilogbf.cpp
+++ b/src/math/generic/ilogbf.cpp
@@ -12,6 +12,6 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::intlogb<int>(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ilogbf128.cpp b/src/math/generic/ilogbf128.cpp
new file mode 100644
index 000000000000..4049eccc5f36
--- /dev/null
+++ b/src/math/generic/ilogbf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ilogbf128 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/ilogbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, ilogbf128, (float128 x)) {
+ return fputil::intlogb<int>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ilogbl.cpp b/src/math/generic/ilogbl.cpp
index 4c18daab1a53..b7f7eb40c441 100644
--- a/src/math/generic/ilogbl.cpp
+++ b/src/math/generic/ilogbl.cpp
@@ -12,6 +12,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) {
+ return fputil::intlogb<int>(x);
+}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/inv_trigf_utils.cpp b/src/math/generic/inv_trigf_utils.cpp
index 8013c0470aff..19c8b997dc4e 100644
--- a/src/math/generic/inv_trigf_utils.cpp
+++ b/src/math/generic/inv_trigf_utils.cpp
@@ -10,19 +10,76 @@
namespace LIBC_NAMESPACE {
-// N[Table[ArcTan[x], {x, 1/16, 16/16, 1/16}], 40]
-alignas(64) const double ATAN_T[ATAN_T_SIZE] = {
- 0x1.ff55bb72cfdeap-5, 0x1.fd5ba9aac2f6ep-4, 0x1.7b97b4bce5b02p-3,
- 0x1.f5b75f92c80ddp-3, 0x1.362773707ebccp-2, 0x1.6f61941e4def1p-2,
- 0x1.a64eec3cc23fdp-2, 0x1.dac670561bb4fp-2, 0x1.0657e94db30d0p-1,
- 0x1.1e00babdefeb4p-1, 0x1.345f01cce37bbp-1, 0x1.4978fa3269ee1p-1,
- 0x1.5d58987169b18p-1, 0x1.700a7c5784634p-1, 0x1.819d0b7158a4dp-1,
- 0x1.921fb54442d18p-1};
-
-// for(int i = 0; i < 5; i++)
-// printf("%.13a,\n", (-2 * (i % 2) + 1) * 1.0 / (2 * i + 1));
-alignas(64) const double ATAN_K[5] = {
- 0x1.0000000000000p+0, -0x1.5555555555555p-2, 0x1.999999999999ap-3,
- -0x1.2492492492492p-3, 0x1.c71c71c71c71cp-4};
+// Polynomial approximation for 0 <= x <= 1:
+// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16)
+// = P(x - i/16)
+// Generated by Sollya with:
+// > for i from 1 to 16 do {
+// mid_point = i/16;
+// P = fpminimax(atan(mid_point + x), 8, [|D...|], [-1/32, 1/32]);
+// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
+// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", coeff(P, 6),
+// ",", coeff(P, 7), ",", coeff(P, 8), "},");
+// };
+// For i = 0, the polynomial is generated by:
+// > P = fpminimax(atan(x)/x, 7, [|1, D...|], [0, 1/32]);
+// > dirtyinfnorm((atan(x) - x*P)/x, [0, 1/32]);
+// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
+// Notice that degree-7 is good enough for atanf, but degree-8 helps reduce the
+// error bounds for atan2f's fast pass 16 times, and it does not affect the
+// performance of atanf much.
+double ATAN_COEFFS[17][9] = {
+ {0.0, 1.0, 0x1.3f8d76d26d61bp-47, -0x1.5555555574cd8p-2,
+ 0x1.0dde5d06878eap-29, 0x1.99997738acc77p-3, 0x1.2c43eac9797cap-16,
+ -0x1.25fb020007dbdp-3, 0x1.c1b6c31d7b0aep-7},
+ {0x1.ff55bb72cfde9p-5, 0x1.fe01fe01fe007p-1, -0x1.fc05f809ed8dap-5,
+ -0x1.4d69303afe04ep-2, 0x1.f61bc3e8349cp-5, 0x1.820839278756bp-3,
+ -0x1.eda4de1c6bf3fp-5, -0x1.0514d42d64a63p-3, 0x1.db3746a442dcbp-5},
+ {0x1.fd5ba9aac2f6ep-4, 0x1.f81f81f81f813p-1, -0x1.f05e09d0dc378p-4,
+ -0x1.368c3aa719215p-2, 0x1.d9b16b33ff9c9p-4, 0x1.40488f9c6262ap-3,
+ -0x1.ba55933e62ea5p-4, -0x1.64c6a15cd9116p-4, 0x1.9273d5939a75ap-4},
+ {0x1.7b97b4bce5b02p-3, 0x1.ee9c7f8458e05p-1, -0x1.665c226d6961p-3,
+ -0x1.1344bb7391703p-2, 0x1.42aca8b0081b9p-3, 0x1.c32d9381d7c03p-4,
+ -0x1.13e970672e246p-3, -0x1.181ed934dd733p-5, 0x1.bad81ea190c08p-4},
+ {0x1.f5b75f92c80ddp-3, 0x1.e1e1e1e1e1e2cp-1, -0x1.c5894d10d363dp-3,
+ -0x1.ce6de025f9f5ep-3, 0x1.78a3a07c8dd7fp-3, 0x1.dd5f5180f386ep-5,
+ -0x1.1b1f513c4536bp-3, 0x1.0df852e58c43cp-6, 0x1.722e7a7e42505p-4},
+ {0x1.362773707ebccp-2, 0x1.d272ca3fc5b2ep-1, -0x1.0997e8aeca8fbp-2,
+ -0x1.6cf6666e5e693p-3, 0x1.8dd1e907e88adp-3, 0x1.24849ac0caa5dp-7,
+ -0x1.f496be486229dp-4, 0x1.b7d54b8e759ecp-5, 0x1.d39c0d39c3922p-5},
+ {0x1.6f61941e4def1p-2, 0x1.c0e070381c0f2p-1, -0x1.2726dd135d9eep-2,
+ -0x1.09f37b39b70e4p-3, 0x1.85eacdaadd712p-3, -0x1.04d66340d5b9p-5,
+ -0x1.8056b15a22b98p-4, 0x1.29baf494ad3ddp-4, 0x1.52d5881322a7ap-6},
+ {0x1.a64eec3cc23fdp-2, 0x1.adbe87f94906ap-1, -0x1.3b9d8eab55addp-2,
+ -0x1.57c09646eb7p-4, 0x1.6795319e3b8dfp-3, -0x1.f2d89b5ef31bep-5,
+ -0x1.f38aac26203cap-5, 0x1.3262802235e3fp-4, -0x1.2afd6b9a57d66p-7},
+ {0x1.dac670561bb4fp-2, 0x1.99999999999ap-1, -0x1.47ae147adff11p-2,
+ -0x1.5d867c40188b7p-5, 0x1.3a92a2df85e7ap-3, -0x1.3ec457c46e851p-4,
+ -0x1.ec1b9777e2e5bp-6, 0x1.0a542992a821ep-4, -0x1.ccffbe2f0d945p-6},
+ {0x1.0657e94db30dp-1, 0x1.84f00c2780615p-1, -0x1.4c62cb562defap-2,
+ -0x1.e6495b3c14e03p-8, 0x1.063c2fa617bfcp-3, -0x1.58b782d9907aap-4,
+ -0x1.41e6ff524b7fp-8, 0x1.937dfff3205a7p-5, -0x1.0fb1fd1c729dp-5},
+ {0x1.1e00babdefeb4p-1, 0x1.702e05c0b816ep-1, -0x1.4af2b78215fbep-2,
+ 0x1.5d0b7e9f36997p-6, 0x1.a1247cb978debp-4, -0x1.519e1457734cap-4,
+ 0x1.a755cf86b5bfbp-7, 0x1.096d174284564p-5, -0x1.081adf539ad58p-5},
+ {0x1.345f01cce37bbp-1, 0x1.5babcc647fa8ep-1, -0x1.449db09426a6dp-2,
+ 0x1.655caac5896dap-5, 0x1.3bbbd22d05a61p-4, -0x1.34a2febee042fp-4,
+ 0x1.84df9c8269e34p-6, 0x1.200e8176c899ap-6, -0x1.c00b23c3ce222p-6},
+ {0x1.4978fa3269ee1p-1, 0x1.47ae147ae1477p-1, -0x1.3a92a3055231ap-2,
+ 0x1.ec21b515a4a2p-5, 0x1.c2f8b81f9a0d2p-5, -0x1.0ba9964125453p-4,
+ 0x1.d7b5614777a05p-6, 0x1.971e91ed73595p-8, -0x1.3fc375a78dc74p-6},
+ {0x1.5d58987169b18p-1, 0x1.34679ace01343p-1, -0x1.2ddfb039136e5p-2,
+ 0x1.2491307b9fb73p-4, 0x1.29c7e4886dc22p-5, -0x1.bca78bcca83ap-5,
+ 0x1.e63efd7cbe1ddp-6, -0x1.8ea6c4f03b42dp-10, -0x1.9385b5c3a6997p-7},
+ {0x1.700a7c5784634p-1, 0x1.21fb78121fb76p-1, -0x1.1f6a8499e5d1ap-2,
+ 0x1.41b15e5e29423p-4, 0x1.59bc953163345p-6, -0x1.63b54b13184ddp-5,
+ 0x1.c9086666d213p-6, -0x1.90c3b4ad8d4bcp-8, -0x1.80f08ed9f6f57p-8},
+ {0x1.819d0b7158a4dp-1, 0x1.107fbbe01107ep-1, -0x1.0feeb4089670ep-2,
+ 0x1.50e5afb93f5cbp-4, 0x1.2a7c2adffeffbp-7, -0x1.12bd29b4f1b43p-5,
+ 0x1.93f71f0eb00eap-6, -0x1.10ece5ad30e28p-7, -0x1.db1a76bcd2b9cp-10},
+ {0x1.921fb54442d18p-1, 0x1.ffffffffffffep-2, -0x1.fffffffffc51cp-3,
+ 0x1.555555557002ep-4, -0x1.a88260c338e75p-30, -0x1.99999f9a7614fp-6,
+ 0x1.555e31a1e15e9p-6, -0x1.245240d65e629p-7, -0x1.fa9ba66478903p-11},
+};
} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/inv_trigf_utils.h b/src/math/generic/inv_trigf_utils.h
index 20f912de2ac0..e60c367d7b46 100644
--- a/src/math/generic/inv_trigf_utils.h
+++ b/src/math/generic/inv_trigf_utils.h
@@ -9,85 +9,33 @@
#ifndef LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
#define LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
-#include "math_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
-#include <errno.h>
-
namespace LIBC_NAMESPACE {
// PI and PI / 2
constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
-// atan table size
-constexpr int ATAN_T_BITS = 4;
-constexpr int ATAN_T_SIZE = 1 << ATAN_T_BITS;
-
-// N[Table[ArcTan[x], {x, 1/8, 8/8, 1/8}], 40]
-extern const double ATAN_T[ATAN_T_SIZE];
-extern const double ATAN_K[5];
-
-// The main idea of the function is to use formula
-// atan(u) + atan(v) = atan((u+v)/(1-uv))
-
-// x should be positive, normal finite value
-LIBC_INLINE double atan_eval(double x) {
- using FPB = fputil::FPBits<double>;
- using Sign = fputil::Sign;
- // Added some small value to umin and umax mantissa to avoid possible rounding
- // errors.
- FPB::StorageType umin =
- FPB::create_value(Sign::POS, FPB::EXP_BIAS - ATAN_T_BITS - 1,
- 0x100000000000UL)
- .uintval();
- FPB::StorageType umax =
- FPB::create_value(Sign::POS, FPB::EXP_BIAS + ATAN_T_BITS,
- 0xF000000000000UL)
- .uintval();
-
- FPB bs(x);
- auto x_abs = bs.abs().uintval();
-
- if (x_abs <= umin) {
- double pe = LIBC_NAMESPACE::fputil::polyeval(
- x * x, 0.0, ATAN_K[1], ATAN_K[2], ATAN_K[3], ATAN_K[4]);
- return fputil::multiply_add(pe, x, x);
- }
-
- if (x_abs >= umax) {
- double one_over_x_m = -1.0 / x;
- double one_over_x2 = one_over_x_m * one_over_x_m;
- double pe = LIBC_NAMESPACE::fputil::polyeval(
- one_over_x2, ATAN_K[0], ATAN_K[1], ATAN_K[2], ATAN_K[3]);
- return fputil::multiply_add(pe, one_over_x_m,
- bs.is_neg() ? (-M_MATH_PI_2) : (M_MATH_PI_2));
- }
+extern double ATAN_COEFFS[17][9];
- double pos_x = FPB(x_abs).get_val();
- bool one_over_x = pos_x > 1.0;
- if (one_over_x) {
- pos_x = 1.0 / pos_x;
- }
+// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
+// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
+LIBC_INLINE double atan_eval(double x, int i) {
+ double x2 = x * x;
- double near_x = fputil::nearest_integer(pos_x * ATAN_T_SIZE);
- int val = static_cast<int>(near_x);
- near_x *= 1.0 / ATAN_T_SIZE;
+ double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
+ double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
+ double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
+ double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
- double v = (pos_x - near_x) / fputil::multiply_add(near_x, pos_x, 1.0);
- double v2 = v * v;
- double pe = LIBC_NAMESPACE::fputil::polyeval(v2, ATAN_K[0], ATAN_K[1],
- ATAN_K[2], ATAN_K[3], ATAN_K[4]);
- double result;
- if (one_over_x)
- result = M_MATH_PI_2 - fputil::multiply_add(pe, v, ATAN_T[val - 1]);
- else
- result = fputil::multiply_add(pe, v, ATAN_T[val - 1]);
- return bs.is_neg() ? -result : result;
+ double x4 = x2 * x2;
+ double d1 = fputil::multiply_add(x2, c1, c0);
+ double d2 = fputil::multiply_add(x2, c3, c2);
+ double p = fputil::multiply_add(x4, d2, d1);
+ return p;
}
// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
diff --git a/src/math/generic/ldexpf128.cpp b/src/math/generic/ldexpf128.cpp
new file mode 100644
index 000000000000..ed2ebd38dfae
--- /dev/null
+++ b/src/math/generic/ldexpf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ldexpf128 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/ldexpf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, ldexpf128, (float128 x, int exp)) {
+ return fputil::ldexp(x, exp);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llogb.cpp b/src/math/generic/llogb.cpp
new file mode 100644
index 000000000000..917bc38c0379
--- /dev/null
+++ b/src/math/generic/llogb.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of llogb 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/llogb.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogb, (double x)) { return fputil::intlogb<long>(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llogbf.cpp b/src/math/generic/llogbf.cpp
new file mode 100644
index 000000000000..ca1c03db5c2e
--- /dev/null
+++ b/src/math/generic/llogbf.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of llogbf 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/llogbf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbf, (float x)) { return fputil::intlogb<long>(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llogbf128.cpp b/src/math/generic/llogbf128.cpp
new file mode 100644
index 000000000000..5ae4af302110
--- /dev/null
+++ b/src/math/generic/llogbf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of llogbf128 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/llogbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbf128, (float128 x)) {
+ return fputil::intlogb<long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llogbl.cpp b/src/math/generic/llogbl.cpp
new file mode 100644
index 000000000000..a092997b9244
--- /dev/null
+++ b/src/math/generic/llogbl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of llogbl 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/llogbl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbl, (long double x)) {
+ return fputil::intlogb<long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llrintf128.cpp b/src/math/generic/llrintf128.cpp
new file mode 100644
index 000000000000..e5a4c50a26e8
--- /dev/null
+++ b/src/math/generic/llrintf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of llrintf128 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/llrintf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long long, llrintf128, (float128 x)) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<float128,
+ long long>(
+ x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/llroundf128.cpp b/src/math/generic/llroundf128.cpp
new file mode 100644
index 000000000000..25791631dd7e
--- /dev/null
+++ b/src/math/generic/llroundf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of llroundf128 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/llroundf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long long, llroundf128, (float128 x)) {
+ return fputil::round_to_signed_integer<float128, long long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/log.cpp b/src/math/generic/log.cpp
index 9edc52b8a8e2..6de0d90be80e 100644
--- a/src/math/generic/log.cpp
+++ b/src/math/generic/log.cpp
@@ -14,6 +14,7 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "common_constants.h"
@@ -23,8 +24,8 @@ namespace LIBC_NAMESPACE {
// 128-bit precision dyadic floating point numbers.
using Float128 = typename fputil::DyadicFloat<128>;
-using MType = typename Float128::MantissaType;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
namespace {
@@ -34,150 +35,152 @@ constexpr double HI_ERR = 0x1.0p-85;
// Extra errors from P is from using x^2 to reduce evaluation latency.
constexpr double P_ERR = 0x1.0p-50;
-// log(2) with 128-bit prepcision generated by SageMath with:
-// sage: (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
-// sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})");
-const Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
- MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab}));
-
-alignas(64) const LogRR LOG_TABLE = {
+// log(2) with 128-bit precision generated by SageMath with:
+// def format_hex(value):
+// l = hex(value)[2:]
+// n = 8
+// x = [l[i:i + n] for i in range(0, len(l), n)]
+// return "0x" + "'".join(x) + "_u128"
+// (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
+// print(format_hex(m));
+constexpr Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
+ 0xb17217f7'd1cf79ab'c9e3b398'03f2f6af_u128);
+
+alignas(64) constexpr LogRR LOG_TABLE = {
// -log(r) with 128-bit precision generated by SageMath with:
- //
// for i in range(128):
// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
- // print("{Sign::POS,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64)
- // % 2^64),
- // "})},");
+ // print("{Sign::POS,", e, ", format_hex(m), "},");
/* .step_1= */ {
- {Sign::POS, 0, MType(0)},
- {Sign::POS, -134, MType({0x662d417ced007a46, 0x8080abac46f38946})},
- {Sign::POS, -133, MType({0x91d082dce3ddcd38, 0x8102b2c49ac23a4f})},
- {Sign::POS, -133, MType({0xda5f3cc0b3251dbd, 0xc24929464655f45c})},
- {Sign::POS, -132, MType({0xb9e3aea6c444ef07, 0x820aec4f3a222380})},
- {Sign::POS, -132, MType({0x521016bd904dc968, 0xa33576a16f1f4c64})},
- {Sign::POS, -132, MType({0xbe97660a23cc540d, 0xc4a550a4fd9a19a8})},
- {Sign::POS, -132, MType({0xe09f5fe2058d6006, 0xe65b9e6eed965c36})},
- {Sign::POS, -131, MType({0x1fecdfa819b96098, 0x842cc5acf1d03445})},
- {Sign::POS, -131, MType({0xa7c9859530a45153, 0x8cb9de8a32ab368a})},
- {Sign::POS, -131, MType({0x976d3b5b45f6ca0b, 0x9defad3e8f73217a})},
- {Sign::POS, -131, MType({0xe8b8b88a14ff0ce, 0xaf4ad26cbc8e5be7})},
- {Sign::POS, -131, MType({0x6a677b4c8bec22e1, 0xb8069857560707a3})},
- {Sign::POS, -131, MType({0xeaf51f66692844ba, 0xc99af2eaca4c4570})},
- {Sign::POS, -131, MType({0xa8112e35a60e6375, 0xdb56446d6ad8deff})},
- {Sign::POS, -131, MType({0x196ab34ce0bccd12, 0xe442c00de2591b47})},
- {Sign::POS, -131, MType({0x4066e87f2c0f7340, 0xf639cc185088fe5d})},
- {Sign::POS, -131, MType({0xc17bd40d8d9291ec, 0xff4489cedeab2ca6})},
- {Sign::POS, -130, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
- {Sign::POS, -130, MType({0x88713268840cbcc0, 0x8d515bf11fb94f1c})},
- {Sign::POS, -130, MType({0x65c0da506a088484, 0x968b08643409ceb6})},
- {Sign::POS, -130, MType({0x411a5b944aca8708, 0x9b2fe580ac80b17d})},
- {Sign::POS, -130, MType({0xa9fb6cf0ecb411b7, 0xa489ec199dab06f2})},
- {Sign::POS, -130, MType({0xcad2fb8d48054ae0, 0xa93f2f250dac67d1})},
- {Sign::POS, -130, MType({0x2c3c2e77904afa78, 0xb2ba75f46099cf8b})},
- {Sign::POS, -130, MType({0x34c7bc3d32750fde, 0xb780945bab55dce4})},
- {Sign::POS, -130, MType({0x9a631e830fd30904, 0xc11e0b2a8d1e0ddb})},
- {Sign::POS, -130, MType({0xaa8b6997a402bf30, 0xc5f57f59c7f46155})},
- {Sign::POS, -130, MType({0x2c507fb7a3d0bf6a, 0xcad2d6e7b80bf914})},
- {Sign::POS, -130, MType({0x5f53bd2e406e66e7, 0xd49f69e456cf1b79})},
- {Sign::POS, -130, MType({0x58a98f2ad65bee9b, 0xd98ec2bade71e539})},
- {Sign::POS, -130, MType({0x4d57da945b5d0aaa, 0xde8439c1dec56877})},
- {Sign::POS, -130, MType({0xc524848e3443e040, 0xe881bf932af3dac0})},
- {Sign::POS, -130, MType({0x11d49f96cb88317b, 0xed89ed86a44a01aa})},
- {Sign::POS, -130, MType({0x3b020fa1820c9492, 0xf29877ff38809091})},
- {Sign::POS, -130, MType({0x54d2238f75f969b1, 0xf7ad6f26e7ff2ef7})},
- {Sign::POS, -130, MType({0xca0cdf301431b60f, 0xfcc8e3659d9bcbec})},
- {Sign::POS, -129, MType({0x62dda9d2270fa1f4, 0x8389c3026ac3139b})},
- {Sign::POS, -129, MType({0x163ceae88f720f1e, 0x86216b3b0b17188b})},
- {Sign::POS, -129, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
- {Sign::POS, -129, MType({0xf7a5168126a58b9a, 0x8b5ae65d67db9acd})},
- {Sign::POS, -129, MType({0x5147bdb6ddcaf59c, 0x8dfccb1ad35ca6ed})},
- {Sign::POS, -129, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -129, MType({0x4a5004f3ef063313, 0x95f783e6e49a9cfa})},
- {Sign::POS, -129, MType({0x2cdec34784707839, 0x98a78f0e9ae71d85})},
- {Sign::POS, -129, MType({0xd878bbe3d392be25, 0x9b5b3bb5f088b766})},
- {Sign::POS, -129, MType({0x5b035eae273a855f, 0x9e1293b9998c1daa})},
- {Sign::POS, -129, MType({0xbb2438273918db7e, 0xa0cda11eaf46390d})},
- {Sign::POS, -129, MType({0xf698298adddd7f32, 0xa38c6e138e20d831})},
- {Sign::POS, -129, MType({0xe4f5275c2d15c21f, 0xa64f04f0b961df76})},
- {Sign::POS, -129, MType({0x8164c759686a2209, 0xa9157039c51ebe70})},
- {Sign::POS, -129, MType({0xf72ea07749ce6bd3, 0xabdfba9e468fd6f6})},
- {Sign::POS, -129, MType({0x7dd6e688ebb13b03, 0xaeadeefacaf97d35})},
- {Sign::POS, -129, MType({0x18ce51fff99479cd, 0xb1801859d56249dc})},
- {Sign::POS, -129, MType({0x2756eba00bc33978, 0xb45641f4e350a0d3})},
- {Sign::POS, -129, MType({0xbe1116c3466beb6d, 0xb730773578cb90b2})},
- {Sign::POS, -129, MType({0x49dc60b2b059a60b, 0xba0ec3b633dd8b09})},
- {Sign::POS, -129, MType({0x2efd17781bb3afec, 0xbcf13343e7d9ec7d})},
- {Sign::POS, -129, MType({0x37eda996244bccb0, 0xbfd7d1dec0a8df6f})},
- {Sign::POS, -129, MType({0x33337789d592e296, 0xc2c2abbb6e5fd56f})},
- {Sign::POS, -129, MType({0x1a18fb8f9f9ef280, 0xc5b1cd44596fa51e})},
- {Sign::POS, -129, MType({0x688ce7c1a75e341a, 0xc8a5431adfb44ca5})},
- {Sign::POS, -129, MType({0x2d7e9307c70c0668, 0xcb9d1a189ab56e76})},
- {Sign::POS, -129, MType({0xef2f3f4f861ad6a9, 0xce995f50af69d861})},
- {Sign::POS, -129, MType({0x7f9d79f51dcc7301, 0xd19a201127d3c645})},
- {Sign::POS, -129, MType({0x7f9d79f51dcc7301, 0xd19a201127d3c645})},
- {Sign::POS, -129, MType({0x5f53bd2e406e66e7, 0xd49f69e456cf1b79})},
- {Sign::POS, -129, MType({0xad88bba7d0cee8e0, 0xd7a94a92466e833a})},
- {Sign::POS, -129, MType({0x96c20cca6efe2ac5, 0xdab7d02231484a92})},
- {Sign::POS, -129, MType({0xf40a666c87842843, 0xddcb08dc0717d85b})},
- {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
- {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
- {Sign::POS, -129, MType({0x3eadb651b49ac53a, 0xe3ffce3a2aa64922})},
- {Sign::POS, -129, MType({0x304e1653e71d9973, 0xe72178c0323a1a0f})},
- {Sign::POS, -129, MType({0xe9a767a80d6d97e8, 0xea481236f7d35baf})},
- {Sign::POS, -129, MType({0x4f91cf4b33e42998, 0xed73aa4264b0ade9})},
- {Sign::POS, -129, MType({0xfc66eb6408ff6433, 0xf0a450d139366ca6})},
- {Sign::POS, -129, MType({0xfc66eb6408ff6433, 0xf0a450d139366ca6})},
- {Sign::POS, -129, MType({0xac8d42f78d3e65d3, 0xf3da161eed6b9aaf})},
- {Sign::POS, -129, MType({0x5a470250d40ebe90, 0xf7150ab5a09f27f4})},
- {Sign::POS, -129, MType({0xb780a545a1b54dcf, 0xfa553f7018c966f2})},
- {Sign::POS, -129, MType({0xb780a545a1b54dcf, 0xfa553f7018c966f2})},
- {Sign::POS, -129, MType({0x8f05924d258c14c5, 0xfd9ac57bd244217e})},
- {Sign::POS, -128, MType({0x89d1b09c70c4010a, 0x8072d72d903d588b})},
- {Sign::POS, -128, MType({0x30d58c3f7e2ea1f, 0x821b05f3b01d6774})},
- {Sign::POS, -128, MType({0x30d58c3f7e2ea1f, 0x821b05f3b01d6774})},
- {Sign::POS, -128, MType({0x20f6fafe8fbb68b9, 0x83c5f8299e2b4091})},
- {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
- {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
- {Sign::POS, -128, MType({0x1e005d06dbfa8f8, 0x87244c308e670a66})},
- {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
- {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
- {Sign::POS, -128, MType({0x2eb628dba173c82d, 0x8a8e1fb794b09134})},
- {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
- {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
- {Sign::POS, -128, MType({0xbddae1ccce247838, 0x8e03c24d73003959})},
- {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
- {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
- {Sign::POS, -128, MType({0x9b92199ed1a4bab1, 0x918586c5f5e4bf01})},
- {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -128, MType({0xf3cbc416a2418012, 0x9513c36876083695})},
- {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
- {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
- {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
- {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
- {Sign::POS, -128, MType({0xe549f9aaea3cb5e1, 0x9a81456cec642e0f})},
- {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
- {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
- {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
- {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
- {Sign::POS, -128, MType({0x67879c5a30cd1242, 0xa00ce1092e5498c3})},
- {Sign::POS, -128, MType({0xb7efae08e597e16, 0xa1ecff97c91e267b})},
- {Sign::POS, -128, MType({0xb7efae08e597e16, 0xa1ecff97c91e267b})},
- {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
- {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
- {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
- {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
- {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
- {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
- {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
- {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
- {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
- {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
- {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
- {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
- {Sign::POS, -128, MType({0x66d235ee63073dd, 0xaf74155120c9011c})},
- {Sign::POS, 0, MType(0)},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -134, 0x8080abac'46f38946'662d417c'ed007a46_u128},
+ {Sign::POS, -133, 0x8102b2c4'9ac23a4f'91d082dc'e3ddcd38_u128},
+ {Sign::POS, -133, 0xc2492946'4655f45c'da5f3cc0'b3251dbd_u128},
+ {Sign::POS, -132, 0x820aec4f'3a222380'b9e3aea6'c444ef07_u128},
+ {Sign::POS, -132, 0xa33576a1'6f1f4c64'521016bd'904dc968_u128},
+ {Sign::POS, -132, 0xc4a550a4'fd9a19a8'be97660a'23cc540d_u128},
+ {Sign::POS, -132, 0xe65b9e6e'ed965c36'e09f5fe2'058d6006_u128},
+ {Sign::POS, -131, 0x842cc5ac'f1d03445'1fecdfa8'19b96098_u128},
+ {Sign::POS, -131, 0x8cb9de8a'32ab368a'a7c98595'30a45153_u128},
+ {Sign::POS, -131, 0x9defad3e'8f73217a'976d3b5b'45f6ca0b_u128},
+ {Sign::POS, -131, 0xaf4ad26c'bc8e5be7'0e8b8b88'a14ff0ce_u128},
+ {Sign::POS, -131, 0xb8069857'560707a3'6a677b4c'8bec22e1_u128},
+ {Sign::POS, -131, 0xc99af2ea'ca4c4570'eaf51f66'692844ba_u128},
+ {Sign::POS, -131, 0xdb56446d'6ad8deff'a8112e35'a60e6375_u128},
+ {Sign::POS, -131, 0xe442c00d'e2591b47'196ab34c'e0bccd12_u128},
+ {Sign::POS, -131, 0xf639cc18'5088fe5d'4066e87f'2c0f7340_u128},
+ {Sign::POS, -131, 0xff4489ce'deab2ca6'c17bd40d'8d9291ec_u128},
+ {Sign::POS, -130, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
+ {Sign::POS, -130, 0x8d515bf1'1fb94f1c'88713268'840cbcc0_u128},
+ {Sign::POS, -130, 0x968b0864'3409ceb6'65c0da50'6a088484_u128},
+ {Sign::POS, -130, 0x9b2fe580'ac80b17d'411a5b94'4aca8708_u128},
+ {Sign::POS, -130, 0xa489ec19'9dab06f2'a9fb6cf0'ecb411b7_u128},
+ {Sign::POS, -130, 0xa93f2f25'0dac67d1'cad2fb8d'48054ae0_u128},
+ {Sign::POS, -130, 0xb2ba75f4'6099cf8b'2c3c2e77'904afa78_u128},
+ {Sign::POS, -130, 0xb780945b'ab55dce4'34c7bc3d'32750fde_u128},
+ {Sign::POS, -130, 0xc11e0b2a'8d1e0ddb'9a631e83'0fd30904_u128},
+ {Sign::POS, -130, 0xc5f57f59'c7f46155'aa8b6997'a402bf30_u128},
+ {Sign::POS, -130, 0xcad2d6e7'b80bf914'2c507fb7'a3d0bf6a_u128},
+ {Sign::POS, -130, 0xd49f69e4'56cf1b79'5f53bd2e'406e66e7_u128},
+ {Sign::POS, -130, 0xd98ec2ba'de71e539'58a98f2a'd65bee9b_u128},
+ {Sign::POS, -130, 0xde8439c1'dec56877'4d57da94'5b5d0aaa_u128},
+ {Sign::POS, -130, 0xe881bf93'2af3dac0'c524848e'3443e040_u128},
+ {Sign::POS, -130, 0xed89ed86'a44a01aa'11d49f96'cb88317b_u128},
+ {Sign::POS, -130, 0xf29877ff'38809091'3b020fa1'820c9492_u128},
+ {Sign::POS, -130, 0xf7ad6f26'e7ff2ef7'54d2238f'75f969b1_u128},
+ {Sign::POS, -130, 0xfcc8e365'9d9bcbec'ca0cdf30'1431b60f_u128},
+ {Sign::POS, -129, 0x8389c302'6ac3139b'62dda9d2'270fa1f4_u128},
+ {Sign::POS, -129, 0x86216b3b'0b17188b'163ceae8'8f720f1e_u128},
+ {Sign::POS, -129, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
+ {Sign::POS, -129, 0x8b5ae65d'67db9acd'f7a51681'26a58b9a_u128},
+ {Sign::POS, -129, 0x8dfccb1a'd35ca6ed'5147bdb6'ddcaf59c_u128},
+ {Sign::POS, -129, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -129, 0x95f783e6'e49a9cfa'4a5004f3'ef063313_u128},
+ {Sign::POS, -129, 0x98a78f0e'9ae71d85'2cdec347'84707839_u128},
+ {Sign::POS, -129, 0x9b5b3bb5'f088b766'd878bbe3'd392be25_u128},
+ {Sign::POS, -129, 0x9e1293b9'998c1daa'5b035eae'273a855f_u128},
+ {Sign::POS, -129, 0xa0cda11e'af46390d'bb243827'3918db7e_u128},
+ {Sign::POS, -129, 0xa38c6e13'8e20d831'f698298a'dddd7f32_u128},
+ {Sign::POS, -129, 0xa64f04f0'b961df76'e4f5275c'2d15c21f_u128},
+ {Sign::POS, -129, 0xa9157039'c51ebe70'8164c759'686a2209_u128},
+ {Sign::POS, -129, 0xabdfba9e'468fd6f6'f72ea077'49ce6bd3_u128},
+ {Sign::POS, -129, 0xaeadeefa'caf97d35'7dd6e688'ebb13b03_u128},
+ {Sign::POS, -129, 0xb1801859'd56249dc'18ce51ff'f99479cd_u128},
+ {Sign::POS, -129, 0xb45641f4'e350a0d3'2756eba0'0bc33978_u128},
+ {Sign::POS, -129, 0xb7307735'78cb90b2'be1116c3'466beb6d_u128},
+ {Sign::POS, -129, 0xba0ec3b6'33dd8b09'49dc60b2'b059a60b_u128},
+ {Sign::POS, -129, 0xbcf13343'e7d9ec7d'2efd1778'1bb3afec_u128},
+ {Sign::POS, -129, 0xbfd7d1de'c0a8df6f'37eda996'244bccb0_u128},
+ {Sign::POS, -129, 0xc2c2abbb'6e5fd56f'33337789'd592e296_u128},
+ {Sign::POS, -129, 0xc5b1cd44'596fa51e'1a18fb8f'9f9ef280_u128},
+ {Sign::POS, -129, 0xc8a5431a'dfb44ca5'688ce7c1'a75e341a_u128},
+ {Sign::POS, -129, 0xcb9d1a18'9ab56e76'2d7e9307'c70c0668_u128},
+ {Sign::POS, -129, 0xce995f50'af69d861'ef2f3f4f'861ad6a9_u128},
+ {Sign::POS, -129, 0xd19a2011'27d3c645'7f9d79f5'1dcc7301_u128},
+ {Sign::POS, -129, 0xd19a2011'27d3c645'7f9d79f5'1dcc7301_u128},
+ {Sign::POS, -129, 0xd49f69e4'56cf1b79'5f53bd2e'406e66e7_u128},
+ {Sign::POS, -129, 0xd7a94a92'466e833a'ad88bba7'd0cee8e0_u128},
+ {Sign::POS, -129, 0xdab7d022'31484a92'96c20cca'6efe2ac5_u128},
+ {Sign::POS, -129, 0xddcb08dc'0717d85b'f40a666c'87842843_u128},
+ {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
+ {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
+ {Sign::POS, -129, 0xe3ffce3a'2aa64922'3eadb651'b49ac53a_u128},
+ {Sign::POS, -129, 0xe72178c0'323a1a0f'304e1653'e71d9973_u128},
+ {Sign::POS, -129, 0xea481236'f7d35baf'e9a767a8'0d6d97e8_u128},
+ {Sign::POS, -129, 0xed73aa42'64b0ade9'4f91cf4b'33e42998_u128},
+ {Sign::POS, -129, 0xf0a450d1'39366ca6'fc66eb64'08ff6433_u128},
+ {Sign::POS, -129, 0xf0a450d1'39366ca6'fc66eb64'08ff6433_u128},
+ {Sign::POS, -129, 0xf3da161e'ed6b9aaf'ac8d42f7'8d3e65d3_u128},
+ {Sign::POS, -129, 0xf7150ab5'a09f27f4'5a470250'd40ebe90_u128},
+ {Sign::POS, -129, 0xfa553f70'18c966f2'b780a545'a1b54dcf_u128},
+ {Sign::POS, -129, 0xfa553f70'18c966f2'b780a545'a1b54dcf_u128},
+ {Sign::POS, -129, 0xfd9ac57b'd244217e'8f05924d'258c14c5_u128},
+ {Sign::POS, -128, 0x8072d72d'903d588b'89d1b09c'70c4010a_u128},
+ {Sign::POS, -128, 0x821b05f3'b01d6774'030d58c3'f7e2ea1f_u128},
+ {Sign::POS, -128, 0x821b05f3'b01d6774'030d58c3'f7e2ea1f_u128},
+ {Sign::POS, -128, 0x83c5f829'9e2b4091'20f6fafe'8fbb68b9_u128},
+ {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
+ {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
+ {Sign::POS, -128, 0x87244c30'8e670a66'01e005d0'6dbfa8f8_u128},
+ {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
+ {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
+ {Sign::POS, -128, 0x8a8e1fb7'94b09134'2eb628db'a173c82d_u128},
+ {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
+ {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
+ {Sign::POS, -128, 0x8e03c24d'73003959'bddae1cc'ce247838_u128},
+ {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
+ {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
+ {Sign::POS, -128, 0x918586c5'f5e4bf01'9b92199e'd1a4bab1_u128},
+ {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -128, 0x9513c368'76083695'f3cbc416'a2418012_u128},
+ {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
+ {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
+ {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
+ {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
+ {Sign::POS, -128, 0x9a81456c'ec642e0f'e549f9aa'ea3cb5e1_u128},
+ {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
+ {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
+ {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
+ {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
+ {Sign::POS, -128, 0xa00ce109'2e5498c3'67879c5a'30cd1242_u128},
+ {Sign::POS, -128, 0xa1ecff97'c91e267b'0b7efae0'8e597e16_u128},
+ {Sign::POS, -128, 0xa1ecff97'c91e267b'0b7efae0'8e597e16_u128},
+ {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
+ {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
+ {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
+ {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
+ {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
+ {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
+ {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
+ {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
+ {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
+ {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
+ {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
+ {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
+ {Sign::POS, -128, 0xaf741551'20c9011c'066d235e'e63073dd_u128},
+ {Sign::POS, 0, 0_u128},
},
// -log(r) for the second step, generated by SageMath with:
//
@@ -185,202 +188,202 @@ alignas(64) const LogRR LOG_TABLE = {
// r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
// print("{Sign::POS," if s == -1 else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_2 = */
{
- {Sign::NEG, -135, MType({0xa1c6f3fc242ef8d0, 0x803faacac419abf2})},
- {Sign::NEG, -136, MType({0xa225ebc02e6d9dd4, 0xfc834da16f0d9f57})},
- {Sign::NEG, -136, MType({0xc33f6ad340ae18a9, 0xf88735ccc7433381})},
- {Sign::NEG, -136, MType({0x70b2a4d38a242244, 0xf48b0e171249b6bc})},
- {Sign::NEG, -136, MType({0x1d54819048b811b0, 0xf08ed67fd190e280})},
- {Sign::NEG, -136, MType({0xaee5983701d2a02b, 0xec928f0686828706})},
- {Sign::NEG, -136, MType({0x40abb8ab72afa2d2, 0xe89637aab2828aed})},
- {Sign::NEG, -136, MType({0xdeb547a0d4a26ef9, 0xe499d06bd6eeead5})},
- {Sign::NEG, -136, MType({0x39c5bdfbcf6087a0, 0xe09d5949751fb909})},
- {Sign::NEG, -136, MType({0x53ea9bf152de635f, 0xdca0d2430e671d18})},
- {Sign::NEG, -136, MType({0x25b820436f5f4352, 0xd8a43b582411537e})},
- {Sign::NEG, -136, MType({0x3c2d13ea1d0be058, 0xd4a794883764ad41})},
- {Sign::NEG, -136, MType({0x4f3cfa62bcb3ce3a, 0xd0aaddd2c9a18f95})},
- {Sign::NEG, -136, MType({0xd0fff6cdf14a86c7, 0xccae17375c02737c})},
- {Sign::NEG, -136, MType({0x7587b5f0453ac3d2, 0xc8b140b56fbbe56a})},
- {Sign::NEG, -136, MType({0xb358ad16dfd0d085, 0xc4b45a4c85fc84e2})},
- {Sign::NEG, -136, MType({0x3c86fdce5dbe7314, 0xc0b763fc1fed041d})},
- {Sign::NEG, -136, MType({0x70764e46ac18a96d, 0xbcba5dc3beb027a6})},
- {Sign::NEG, -136, MType({0xc63be62b8f285882, 0xb8bd47a2e362c600})},
- {Sign::NEG, -136, MType({0x72e7b5a386e5e31b, 0xb3c0d59a244325a4})},
- {Sign::NEG, -136, MType({0xc3ea2cd93f316b34, 0xafc39bac66434f27})},
- {Sign::NEG, -136, MType({0x1dfb11a7cc892843, 0xabc651d491a7b438})},
- {Sign::NEG, -136, MType({0xfc679a28e9d9f212, 0xa7c8f8122773f38d})},
- {Sign::NEG, -136, MType({0xe7bc977eeec42254, 0xa3cb8e64a8a5bbe6})},
- {Sign::NEG, -136, MType({0xb20f215bd3b58c61, 0x9fce14cb9634cba6})},
- {Sign::NEG, -136, MType({0xabe2862508d67a98, 0x9bd08b467112f078})},
- {Sign::NEG, -136, MType({0xd1aacedcefe9d377, 0x97d2f1d4ba2c06f0})},
- {Sign::NEG, -136, MType({0xf1eb25e77d05f58d, 0x93d54875f265fa2c})},
- {Sign::NEG, -136, MType({0xcbef6fac33691e95, 0x8fd78f299aa0c375})},
- {Sign::NEG, -136, MType({0x2720640462a0f8ad, 0x8bd9c5ef33b669e0})},
- {Sign::NEG, -136, MType({0xe2f1775134c8da75, 0x87dbecc63e7b01ed})},
- {Sign::NEG, -136, MType({0xff67e201c8c50d67, 0x83de03ae3bbcad2e})},
- {Sign::NEG, -137, MType({0x3c742a7c76356396, 0xffc0154d588733c5})},
- {Sign::NEG, -137, MType({0xf90dd6b24aa686ec, 0xf7c4035e21a4052f})},
- {Sign::NEG, -137, MType({0xca47c52b7d7ffce2, 0xefc7d18dd4485b9e})},
- {Sign::NEG, -137, MType({0x3703617ad3d8311f, 0xe7cb7fdb71e0db36})},
- {Sign::NEG, -137, MType({0x7e4cfbd830393b88, 0xdfcf0e45fbce3e80})},
- {Sign::NEG, -137, MType({0x4f7a29cf0fc2c38e, 0xd7d27ccc736555af})},
- {Sign::NEG, -137, MType({0x7370ae83f9e72748, 0xcfd5cb6dd9ef05dd})},
- {Sign::NEG, -137, MType({0x671486eb4cd76f65, 0xc7d8fa2930a84850})},
- {Sign::NEG, -137, MType({0xe6dbb624f9739782, 0xbfdc08fd78c229b9})},
- {Sign::NEG, -137, MType({0x6b866e09e57d9079, 0xb7def7e9b361c979})},
- {Sign::NEG, -137, MType({0x97fa2fd0c9dc723e, 0xafe1c6ece1a058dd})},
- {Sign::NEG, -137, MType({0x983e80897cf1e60f, 0xa7e47606048b1a65})},
- {Sign::NEG, -137, MType({0x7199cd06ae5d39b3, 0x9fe705341d236102})},
- {Sign::NEG, -137, MType({0x43cd18a72a051a96, 0x97e974762c5e8f58})},
- {Sign::NEG, -137, MType({0x7b6d1248c3e1fd40, 0x8febc3cb332616ff})},
- {Sign::NEG, -137, MType({0xf5572a8814c703af, 0x87edf332325777c5})},
- {Sign::NEG, -138, MType({0x26828c92649a3a39, 0xffe0055455887de0})},
- {Sign::NEG, -138, MType({0x82c550bd1216d82a, 0xefe3e4643a640cf3})},
- {Sign::NEG, -138, MType({0xda6959f7f0e01bf0, 0xdfe7839214b4e8ae})},
- {Sign::NEG, -138, MType({0xda93e2fa85a8f214, 0xcfeae2dbe5d6736d})},
- {Sign::NEG, -138, MType({0xb47505bfa5a03b06, 0xbfee023faf0c2480})},
- {Sign::NEG, -138, MType({0xb1475a5180a43520, 0xaff0e1bb718186ad})},
- {Sign::NEG, -138, MType({0xa8740b91c95df537, 0x9ff3814d2e4a36b2})},
- {Sign::NEG, -138, MType({0x57d895d35921b59c, 0x8ff5e0f2e661e1c6})},
- {Sign::NEG, -139, MType({0x3c56c598c659c2a3, 0xfff0015535588833})},
- {Sign::NEG, -139, MType({0x2ef8ec33ed9d782a, 0xdff3c0e497ea4eb1})},
- {Sign::NEG, -139, MType({0x379eba7e6465ff63, 0xbff7008ff5e0c257})},
- {Sign::NEG, -139, MType({0x3f972b783fcab757, 0x9ff9c0535073a370})},
- {Sign::NEG, -140, MType({0xde026e271ee0549d, 0xfff8005551558885})},
- {Sign::NEG, -140, MType({0xeceb47ea01f6c632, 0xbffb8023febc0c25})},
- {Sign::NEG, -141, MType({0x7333c57857e1ed52, 0xfffc001554d55888})},
- {Sign::NEG, -142, MType({0x87dde026fa704374, 0xfffe000555455588})},
- {Sign::NEG, 0, MType({0x0, 0x0})},
- {Sign::POS, -141, MType({0x44999abe2fe2cc65, 0x80010002aab2aac4})},
- {Sign::POS, -140, MType({0x4eef381581464ccb, 0x8002000aaaeaac44})},
- {Sign::POS, -140, MType({0xdfeb485085f6f454, 0xc004802401440c26})},
- {Sign::POS, -139, MType({0x99abe3be3a1c6e93, 0x8004002aacaac445})},
- {Sign::POS, -139, MType({0x6bc1e20eac8448b4, 0xa00640535a37a37a})},
- {Sign::POS, -139, MType({0x979eedc064c242fd, 0xc00900900a20c275})},
- {Sign::POS, -139, MType({0xc72446cc1bf728bd, 0xe00c40e4bd6e4efd})},
- {Sign::POS, -138, MType({0xf381b821bbb569e5, 0x800800aabaac446e})},
- {Sign::POS, -138, MType({0x569b26aaa485ea5c, 0x900a20f319a3e273})},
- {Sign::POS, -138, MType({0x2dcf56c83c80b028, 0xa00c814d7c6a37f8})},
- {Sign::POS, -138, MType({0x5f69768284463b9b, 0xb00f21bbe3e388ee})},
- {Sign::POS, -138, MType({0xb48ea6c05e2773a1, 0xc0120240510c284c})},
- {Sign::POS, -138, MType({0x14d9d76196d8043a, 0xd01522dcc4f87991})},
- {Sign::POS, -138, MType({0xe016a611a4415d72, 0xe018839340d4f241})},
- {Sign::POS, -138, MType({0x661e135f49a47c40, 0xf01c2465c5e61b6f})},
- {Sign::POS, -137, MType({0xbe6bf0fa435e8383, 0x801002ab2ac4499a})},
- {Sign::POS, -137, MType({0x9a31ba0cbc030353, 0x881213337898871e})},
- {Sign::POS, -137, MType({0x54b57dfe0c4c840f, 0x901443cccd362c9f})},
- {Sign::POS, -137, MType({0x7ad1e9c315328f7e, 0x98169478296fad41})},
- {Sign::POS, -137, MType({0x1f3f686cf3d6be22, 0xa01905368e2389b3})},
- {Sign::POS, -137, MType({0xf105b66ec4703ede, 0xa81b9608fc3c50ec})},
- {Sign::POS, -137, MType({0x610848c68df4d233, 0xb01e46f074b0a0f3})},
- {Sign::POS, -137, MType({0xd6aef30cd312169a, 0xb82117edf8832797})},
- {Sign::POS, -137, MType({0xf3ac379608053d9d, 0xc024090288c2a339})},
- {Sign::POS, -137, MType({0xe6e2acf8f4d4c24a, 0xc8271a2f2689e388})},
- {Sign::POS, -137, MType({0xce6ae474d860359f, 0xd02a4b74d2ffca44})},
- {Sign::POS, -137, MType({0x28bb3cd9f2a65fb5, 0xd82d9cd48f574c00})},
- {Sign::POS, -137, MType({0x54f30dbef38a8066, 0xe0310e4f5ccf70e1})},
- {Sign::POS, -137, MType({0x224a96f5a7471c46, 0xe8349fe63cb35564})},
- {Sign::POS, -137, MType({0x6ea920591aa02e1b, 0xf038519a305a2b1b})},
- {Sign::POS, -137, MType({0xd462b63756c87e80, 0xf83c236c39273972})},
- {Sign::POS, -136, MType({0x338f77605fe77f2a, 0x80200aaeac44ef38})},
- {Sign::POS, -136, MType({0x3ff51287882500ed, 0x842213b747fec7bb})},
- {Sign::POS, -136, MType({0xcc394b3ef0ebeb12, 0x88242cd07084ed02})},
- {Sign::POS, -136, MType({0x1ab9679b55f78a6b, 0x8c2655faa6a1323f})},
- {Sign::POS, -136, MType({0x7025697d10af0436, 0x90288f366b237771})},
- {Sign::POS, -136, MType({0x17e4b7ac6c600cb4, 0x942ad8843ee1a9cd})},
- {Sign::POS, -136, MType({0x7013925a9a8da7f3, 0x982d31e4a2b7c418})},
- {Sign::POS, -136, MType({0xfd1a09c848e3950e, 0x9c2f9b581787cf0d})},
- {Sign::POS, -136, MType({0x84dd2de6e3d90a37, 0xa03214df1e39e1bd})},
- {Sign::POS, -136, MType({0x318b2ddd9d0a33b4, 0xa4349e7a37bc21ed})},
- {Sign::POS, -136, MType({0xbc031e6f5acfd4a8, 0xa8373829e502c47a})},
- {Sign::POS, -136, MType({0x9dd91e52c79fd070, 0xac39e1eea7080dbc})},
- {Sign::POS, -136, MType({0x4af78fa1cb48a12d, 0xb03c9bc8fecc51e3})},
- {Sign::POS, -136, MType({0x72de1d99ce252efd, 0xb43f65b96d55f55a})},
- {Sign::POS, -136, MType({0xefb1dbe721934877, 0xb74187bc8ccffa84})},
- {Sign::POS, -136, MType({0xb4b080f230c87598, 0xbb446dd4d9bca499})},
- {Sign::POS, -136, MType({0xda6a7cd19c7fa4f2, 0xbf476404a05f88f2})},
- {Sign::POS, -136, MType({0xdf00e3783b50ecfb, 0xc34a6a4c61d5cc3c})},
- {Sign::POS, -136, MType({0xda2e5e02ab4e183c, 0xc74d80ac9f42a52d})},
- {Sign::POS, -136, MType({0xea5f6ee99d30c626, 0xcb50a725d9cf5ce6})},
- {Sign::POS, -136, MType({0xa96d5956531d7d8b, 0xcf53ddb892ab4f55})},
- {Sign::POS, -136, MType({0xa8fc636eb36afa75, 0xd35724654b0beb95})},
- {Sign::POS, -136, MType({0xf67e2b827bfc4421, 0xd75a7b2c842cb451})},
- {Sign::POS, -136, MType({0xa6d8c817516303e6, 0xdb5de20ebf4f4026})},
- {Sign::POS, -136, MType({0x69b36ae5962e85f4, 0xdf61590c7dbb3a02})},
- {Sign::POS, -136, MType({0x24693eec2a831cc3, 0xe364e02640be6188})},
- {Sign::POS, -136, MType({0x94a339d56a55ab4a, 0xe768775c89ac8b70})},
- {Sign::POS, -136, MType({0xfa9998fbf9703bf4, 0xeb6c1eafd9dfa1eb})},
- {Sign::POS, -136, MType({0xcafdc27227b71eaa, 0xef6fd620b2b7a503})},
- {Sign::POS, -136, MType({0x688d4282f6026aa3, 0xf3739daf959aaafc})},
- {Sign::POS, -136, MType({0xe54e9e3804464cdd, 0xf777755d03f4e0b6})},
- {Sign::POS, -136, MType({0xcb78b383f4b59dce, 0xfb7b5d297f388a12})},
- {Sign::POS, -136, MType({0xee055fc515062c04, 0xff7f551588de024f})},
- {Sign::POS, -135, MType({0x207812b43382acdd, 0x81c1ae90d131de38})},
- {Sign::POS, -135, MType({0xdc90c4c4b61f3a87, 0x83c3baa726a721cc})},
- {Sign::POS, -135, MType({0x1a03f13fb2c978b1, 0x85c5cece05941dbc})},
- {Sign::POS, -135, MType({0xb36f282e83a7dc36, 0x87c7eb05aec1304f})},
- {Sign::POS, -135, MType({0x6ad14c3dfa414391, 0x89ca0f4e62f9c476})},
- {Sign::POS, -135, MType({0xe8dd4ea0d48b88e5, 0x8bcc3ba8630c51f4})},
- {Sign::POS, -135, MType({0xc02515afe8caeb90, 0x8dce7013efca5d96})},
- {Sign::POS, -135, MType({0x741ceaf3349f3cf1, 0x8fd0ac914a08795f})},
- {Sign::POS, -135, MType({0x83f7cd4929d2c28c, 0x91d2f120b29e44bb})},
- {Sign::POS, -135, MType({0x795d03ebc2fd03fa, 0x93d53dc26a666cb1})},
- {Sign::POS, -135, MType({0xfaf74f1d1ad16acc, 0x95d79276b23eac12})},
- {Sign::POS, -135, MType({0xe2de134f72fee429, 0x97d9ef3dcb07cbad})},
- {Sign::POS, -135, MType({0x58d8dba6cadac5d5, 0x99dc5417f5a5a27d})},
- {Sign::POS, -135, MType({0xf07d90bc5aae40a4, 0x9bdec10572ff15da})},
- {Sign::POS, -135, MType({0x1deaf79d9fc40374, 0x9d6098046659ea6b})},
- {Sign::POS, -135, MType({0x7ba63e6769b81999, 0x9f63131450b07988})},
- {Sign::POS, -135, MType({0x59ebfc9335094e59, 0xa1659638404d5f92})},
- {Sign::POS, -135, MType({0x16aae012b5026f71, 0xa36821707622f97a})},
- {Sign::POS, -135, MType({0xff5d4f2c0e4b9cae, 0xa56ab4bd3326b378})},
- {Sign::POS, -135, MType({0x855838b5119dcb28, 0xa76d501eb8510941})},
- {Sign::POS, -135, MType({0x75f70cbbe9cf1603, 0xa96ff395469d8630})},
- {Sign::POS, -135, MType({0x36a53ad4d5541cc9, 0xab729f211f0ac57e})},
- {Sign::POS, -135, MType({0x4c5934ec32d20d9, 0xad7552c2829a7270})},
- {Sign::POS, -135, MType({0x3977e89aec59bfa2, 0xaf780e79b2514889})},
- {Sign::POS, -135, MType({0x913d4e3dc55c3e6e, 0xb17ad246ef3713bc})},
- {Sign::POS, -135, MType({0x777b52a9e70d8bcc, 0xb37d9e2a7a56b09d})},
- {Sign::POS, -135, MType({0x55de916fd30591de, 0xb580722494be0c91})},
- {Sign::POS, -135, MType({0xe79cfb37be2861e4, 0xb7834e357f7e2600})},
- {Sign::POS, -135, MType({0x90983104d3805389, 0xb986325d7bab0c89})},
- {Sign::POS, -135, MType({0xb860504baa6f984d, 0xbb891e9cca5be12e})},
- {Sign::POS, -135, MType({0x29178d6ff5712b96, 0xbd8c12f3acaad68b})},
- {Sign::POS, -135, MType({0x7236fa47ba19a198, 0xbf8f0f6263b53102})},
- {Sign::POS, -135, MType({0x4f34d64cafcc50e3, 0xc19213e9309b46f2})},
- {Sign::POS, -135, MType({0x120cc62eb0a8db3e, 0xc3952088548080e4})},
- {Sign::POS, -135, MType({0x11aa5084779060e3, 0xc5983540108b59be})},
- {Sign::POS, -135, MType({0x1c35fd6236c8dcf1, 0xc79b5210a5e55ef5})},
- {Sign::POS, -135, MType({0xed4576a7e4b878fe, 0xc99e76fa55bb30bd})},
- {Sign::POS, -135, MType({0x6caf4bb8fd2c1131, 0xcb20d7fa3a336081})},
- {Sign::POS, -135, MType({0x3f24a6cbb09c654f, 0xcd240b10753e78de})},
- {Sign::POS, -135, MType({0x78bc003bb81e40f3, 0xcf2746407e0ff09f})},
- {Sign::POS, -135, MType({0x56647301edfd8e8b, 0xd12a898a95dff002})},
- {Sign::POS, -135, MType({0x28fe1c4d04ca4ed9, 0xd32dd4eefde9b2ef})},
- {Sign::POS, -135, MType({0xe1ea9ea6cbf57379, 0xd531286df76b892a})},
- {Sign::POS, -135, MType({0xa3832028141a5cc2, 0xd7348407c3a6d688})},
- {Sign::POS, -135, MType({0x557421dd379d3ead, 0xd937e7bca3e0131b})},
- {Sign::POS, -135, MType({0x3cff8e87a99bcaf0, 0xdb3b538cd95ecb67})},
- {Sign::POS, -135, MType({0x99255ef34bd0801f, 0xdd3ec778a56da093})},
- {Sign::POS, -135, MType({0x42b33220abfa15cd, 0xdf424380495a489c})},
- {Sign::POS, -135, MType({0x503b378faa97dbc0, 0xe145c7a406758e83})},
- {Sign::POS, -135, MType({0xbdf2ca006f59b544, 0xe34953e41e135282})},
- {Sign::POS, -135, MType({0x1979190af37ed16f, 0xe54ce840d18a8a3e})},
- {Sign::POS, -135, MType({0x31863ff7cf898c9c, 0xe75084ba623540f4})},
- {Sign::POS, -135, MType({0xc983284f60293647, 0xe9542951117097b0})},
- {Sign::POS, -135, MType({0x510a969ebe03f804, 0xeb57d605209cc57e})},
- {Sign::POS, -135, MType({0x9f53bffc6d23fe30, 0xed5b8ad6d11d1797})},
- {Sign::POS, -135, MType({0xb286c6e113337886, 0xef5f47c66457f199})},
- {Sign::POS, -135, MType({0xb6ed80852ae6fd63, 0xf0e21acdd6e7d412})},
- {Sign::POS, -135, MType({0xdf437fb0f616082d, 0xf2e5e5f25450c5a2})},
- {Sign::POS, -135, MType({0xf237cff1acb306b3, 0xf4e9b935685dbe0b})},
- {Sign::POS, -135, MType({0x52dbfafb4121a092, 0xf6ed94975480b696})},
- {Sign::POS, -135, MType({0xd81648249cece4c, 0xf8f178185a2ebfd9})},
- {Sign::POS, -135, MType({0xad95e6b0b96903d3, 0xfaf563b8bae001eb})},
- {Sign::POS, -135, MType({0x176cd56887ac7fe9, 0xfcf95778b80fbc98})},
- {Sign::POS, -135, MType({0x65f4c7397f1f478d, 0xfefd5358933c478c})},
+ {Sign::NEG, -135, 0x803faaca'c419abf2'a1c6f3fc'242ef8d0_u128},
+ {Sign::NEG, -136, 0xfc834da1'6f0d9f57'a225ebc0'2e6d9dd4_u128},
+ {Sign::NEG, -136, 0xf88735cc'c7433381'c33f6ad3'40ae18a9_u128},
+ {Sign::NEG, -136, 0xf48b0e17'1249b6bc'70b2a4d3'8a242244_u128},
+ {Sign::NEG, -136, 0xf08ed67f'd190e280'1d548190'48b811b0_u128},
+ {Sign::NEG, -136, 0xec928f06'86828706'aee59837'01d2a02b_u128},
+ {Sign::NEG, -136, 0xe89637aa'b2828aed'40abb8ab'72afa2d2_u128},
+ {Sign::NEG, -136, 0xe499d06b'd6eeead5'deb547a0'd4a26ef9_u128},
+ {Sign::NEG, -136, 0xe09d5949'751fb909'39c5bdfb'cf6087a0_u128},
+ {Sign::NEG, -136, 0xdca0d243'0e671d18'53ea9bf1'52de635f_u128},
+ {Sign::NEG, -136, 0xd8a43b58'2411537e'25b82043'6f5f4352_u128},
+ {Sign::NEG, -136, 0xd4a79488'3764ad41'3c2d13ea'1d0be058_u128},
+ {Sign::NEG, -136, 0xd0aaddd2'c9a18f95'4f3cfa62'bcb3ce3a_u128},
+ {Sign::NEG, -136, 0xccae1737'5c02737c'd0fff6cd'f14a86c7_u128},
+ {Sign::NEG, -136, 0xc8b140b5'6fbbe56a'7587b5f0'453ac3d2_u128},
+ {Sign::NEG, -136, 0xc4b45a4c'85fc84e2'b358ad16'dfd0d085_u128},
+ {Sign::NEG, -136, 0xc0b763fc'1fed041d'3c86fdce'5dbe7314_u128},
+ {Sign::NEG, -136, 0xbcba5dc3'beb027a6'70764e46'ac18a96d_u128},
+ {Sign::NEG, -136, 0xb8bd47a2'e362c600'c63be62b'8f285882_u128},
+ {Sign::NEG, -136, 0xb3c0d59a'244325a4'72e7b5a3'86e5e31b_u128},
+ {Sign::NEG, -136, 0xafc39bac'66434f27'c3ea2cd9'3f316b34_u128},
+ {Sign::NEG, -136, 0xabc651d4'91a7b438'1dfb11a7'cc892843_u128},
+ {Sign::NEG, -136, 0xa7c8f812'2773f38d'fc679a28'e9d9f212_u128},
+ {Sign::NEG, -136, 0xa3cb8e64'a8a5bbe6'e7bc977e'eec42254_u128},
+ {Sign::NEG, -136, 0x9fce14cb'9634cba6'b20f215b'd3b58c61_u128},
+ {Sign::NEG, -136, 0x9bd08b46'7112f078'abe28625'08d67a98_u128},
+ {Sign::NEG, -136, 0x97d2f1d4'ba2c06f0'd1aacedc'efe9d377_u128},
+ {Sign::NEG, -136, 0x93d54875'f265fa2c'f1eb25e7'7d05f58d_u128},
+ {Sign::NEG, -136, 0x8fd78f29'9aa0c375'cbef6fac'33691e95_u128},
+ {Sign::NEG, -136, 0x8bd9c5ef'33b669e0'27206404'62a0f8ad_u128},
+ {Sign::NEG, -136, 0x87dbecc6'3e7b01ed'e2f17751'34c8da75_u128},
+ {Sign::NEG, -136, 0x83de03ae'3bbcad2e'ff67e201'c8c50d67_u128},
+ {Sign::NEG, -137, 0xffc0154d'588733c5'3c742a7c'76356396_u128},
+ {Sign::NEG, -137, 0xf7c4035e'21a4052f'f90dd6b2'4aa686ec_u128},
+ {Sign::NEG, -137, 0xefc7d18d'd4485b9e'ca47c52b'7d7ffce2_u128},
+ {Sign::NEG, -137, 0xe7cb7fdb'71e0db36'3703617a'd3d8311f_u128},
+ {Sign::NEG, -137, 0xdfcf0e45'fbce3e80'7e4cfbd8'30393b88_u128},
+ {Sign::NEG, -137, 0xd7d27ccc'736555af'4f7a29cf'0fc2c38e_u128},
+ {Sign::NEG, -137, 0xcfd5cb6d'd9ef05dd'7370ae83'f9e72748_u128},
+ {Sign::NEG, -137, 0xc7d8fa29'30a84850'671486eb'4cd76f65_u128},
+ {Sign::NEG, -137, 0xbfdc08fd'78c229b9'e6dbb624'f9739782_u128},
+ {Sign::NEG, -137, 0xb7def7e9'b361c979'6b866e09'e57d9079_u128},
+ {Sign::NEG, -137, 0xafe1c6ec'e1a058dd'97fa2fd0'c9dc723e_u128},
+ {Sign::NEG, -137, 0xa7e47606'048b1a65'983e8089'7cf1e60f_u128},
+ {Sign::NEG, -137, 0x9fe70534'1d236102'7199cd06'ae5d39b3_u128},
+ {Sign::NEG, -137, 0x97e97476'2c5e8f58'43cd18a7'2a051a96_u128},
+ {Sign::NEG, -137, 0x8febc3cb'332616ff'7b6d1248'c3e1fd40_u128},
+ {Sign::NEG, -137, 0x87edf332'325777c5'f5572a88'14c703af_u128},
+ {Sign::NEG, -138, 0xffe00554'55887de0'26828c92'649a3a39_u128},
+ {Sign::NEG, -138, 0xefe3e464'3a640cf3'82c550bd'1216d82a_u128},
+ {Sign::NEG, -138, 0xdfe78392'14b4e8ae'da6959f7'f0e01bf0_u128},
+ {Sign::NEG, -138, 0xcfeae2db'e5d6736d'da93e2fa'85a8f214_u128},
+ {Sign::NEG, -138, 0xbfee023f'af0c2480'b47505bf'a5a03b06_u128},
+ {Sign::NEG, -138, 0xaff0e1bb'718186ad'b1475a51'80a43520_u128},
+ {Sign::NEG, -138, 0x9ff3814d'2e4a36b2'a8740b91'c95df537_u128},
+ {Sign::NEG, -138, 0x8ff5e0f2'e661e1c6'57d895d3'5921b59c_u128},
+ {Sign::NEG, -139, 0xfff00155'35588833'3c56c598'c659c2a3_u128},
+ {Sign::NEG, -139, 0xdff3c0e4'97ea4eb1'2ef8ec33'ed9d782a_u128},
+ {Sign::NEG, -139, 0xbff7008f'f5e0c257'379eba7e'6465ff63_u128},
+ {Sign::NEG, -139, 0x9ff9c053'5073a370'3f972b78'3fcab757_u128},
+ {Sign::NEG, -140, 0xfff80055'51558885'de026e27'1ee0549d_u128},
+ {Sign::NEG, -140, 0xbffb8023'febc0c25'eceb47ea'01f6c632_u128},
+ {Sign::NEG, -141, 0xfffc0015'54d55888'7333c578'57e1ed52_u128},
+ {Sign::NEG, -142, 0xfffe0005'55455588'87dde026'fa704374_u128},
+ {Sign::NEG, 0, 0_u128},
+ {Sign::POS, -141, 0x80010002'aab2aac4'44999abe'2fe2cc65_u128},
+ {Sign::POS, -140, 0x8002000a'aaeaac44'4eef3815'81464ccb_u128},
+ {Sign::POS, -140, 0xc0048024'01440c26'dfeb4850'85f6f454_u128},
+ {Sign::POS, -139, 0x8004002a'acaac445'99abe3be'3a1c6e93_u128},
+ {Sign::POS, -139, 0xa0064053'5a37a37a'6bc1e20e'ac8448b4_u128},
+ {Sign::POS, -139, 0xc0090090'0a20c275'979eedc0'64c242fd_u128},
+ {Sign::POS, -139, 0xe00c40e4'bd6e4efd'c72446cc'1bf728bd_u128},
+ {Sign::POS, -138, 0x800800aa'baac446e'f381b821'bbb569e5_u128},
+ {Sign::POS, -138, 0x900a20f3'19a3e273'569b26aa'a485ea5c_u128},
+ {Sign::POS, -138, 0xa00c814d'7c6a37f8'2dcf56c8'3c80b028_u128},
+ {Sign::POS, -138, 0xb00f21bb'e3e388ee'5f697682'84463b9b_u128},
+ {Sign::POS, -138, 0xc0120240'510c284c'b48ea6c0'5e2773a1_u128},
+ {Sign::POS, -138, 0xd01522dc'c4f87991'14d9d761'96d8043a_u128},
+ {Sign::POS, -138, 0xe0188393'40d4f241'e016a611'a4415d72_u128},
+ {Sign::POS, -138, 0xf01c2465'c5e61b6f'661e135f'49a47c40_u128},
+ {Sign::POS, -137, 0x801002ab'2ac4499a'be6bf0fa'435e8383_u128},
+ {Sign::POS, -137, 0x88121333'7898871e'9a31ba0c'bc030353_u128},
+ {Sign::POS, -137, 0x901443cc'cd362c9f'54b57dfe'0c4c840f_u128},
+ {Sign::POS, -137, 0x98169478'296fad41'7ad1e9c3'15328f7e_u128},
+ {Sign::POS, -137, 0xa0190536'8e2389b3'1f3f686c'f3d6be22_u128},
+ {Sign::POS, -137, 0xa81b9608'fc3c50ec'f105b66e'c4703ede_u128},
+ {Sign::POS, -137, 0xb01e46f0'74b0a0f3'610848c6'8df4d233_u128},
+ {Sign::POS, -137, 0xb82117ed'f8832797'd6aef30c'd312169a_u128},
+ {Sign::POS, -137, 0xc0240902'88c2a339'f3ac3796'08053d9d_u128},
+ {Sign::POS, -137, 0xc8271a2f'2689e388'e6e2acf8'f4d4c24a_u128},
+ {Sign::POS, -137, 0xd02a4b74'd2ffca44'ce6ae474'd860359f_u128},
+ {Sign::POS, -137, 0xd82d9cd4'8f574c00'28bb3cd9'f2a65fb5_u128},
+ {Sign::POS, -137, 0xe0310e4f'5ccf70e1'54f30dbe'f38a8066_u128},
+ {Sign::POS, -137, 0xe8349fe6'3cb35564'224a96f5'a7471c46_u128},
+ {Sign::POS, -137, 0xf038519a'305a2b1b'6ea92059'1aa02e1b_u128},
+ {Sign::POS, -137, 0xf83c236c'39273972'd462b637'56c87e80_u128},
+ {Sign::POS, -136, 0x80200aae'ac44ef38'338f7760'5fe77f2a_u128},
+ {Sign::POS, -136, 0x842213b7'47fec7bb'3ff51287'882500ed_u128},
+ {Sign::POS, -136, 0x88242cd0'7084ed02'cc394b3e'f0ebeb12_u128},
+ {Sign::POS, -136, 0x8c2655fa'a6a1323f'1ab9679b'55f78a6b_u128},
+ {Sign::POS, -136, 0x90288f36'6b237771'7025697d'10af0436_u128},
+ {Sign::POS, -136, 0x942ad884'3ee1a9cd'17e4b7ac'6c600cb4_u128},
+ {Sign::POS, -136, 0x982d31e4'a2b7c418'7013925a'9a8da7f3_u128},
+ {Sign::POS, -136, 0x9c2f9b58'1787cf0d'fd1a09c8'48e3950e_u128},
+ {Sign::POS, -136, 0xa03214df'1e39e1bd'84dd2de6'e3d90a37_u128},
+ {Sign::POS, -136, 0xa4349e7a'37bc21ed'318b2ddd'9d0a33b4_u128},
+ {Sign::POS, -136, 0xa8373829'e502c47a'bc031e6f'5acfd4a8_u128},
+ {Sign::POS, -136, 0xac39e1ee'a7080dbc'9dd91e52'c79fd070_u128},
+ {Sign::POS, -136, 0xb03c9bc8'fecc51e3'4af78fa1'cb48a12d_u128},
+ {Sign::POS, -136, 0xb43f65b9'6d55f55a'72de1d99'ce252efd_u128},
+ {Sign::POS, -136, 0xb74187bc'8ccffa84'efb1dbe7'21934877_u128},
+ {Sign::POS, -136, 0xbb446dd4'd9bca499'b4b080f2'30c87598_u128},
+ {Sign::POS, -136, 0xbf476404'a05f88f2'da6a7cd1'9c7fa4f2_u128},
+ {Sign::POS, -136, 0xc34a6a4c'61d5cc3c'df00e378'3b50ecfb_u128},
+ {Sign::POS, -136, 0xc74d80ac'9f42a52d'da2e5e02'ab4e183c_u128},
+ {Sign::POS, -136, 0xcb50a725'd9cf5ce6'ea5f6ee9'9d30c626_u128},
+ {Sign::POS, -136, 0xcf53ddb8'92ab4f55'a96d5956'531d7d8b_u128},
+ {Sign::POS, -136, 0xd3572465'4b0beb95'a8fc636e'b36afa75_u128},
+ {Sign::POS, -136, 0xd75a7b2c'842cb451'f67e2b82'7bfc4421_u128},
+ {Sign::POS, -136, 0xdb5de20e'bf4f4026'a6d8c817'516303e6_u128},
+ {Sign::POS, -136, 0xdf61590c'7dbb3a02'69b36ae5'962e85f4_u128},
+ {Sign::POS, -136, 0xe364e026'40be6188'24693eec'2a831cc3_u128},
+ {Sign::POS, -136, 0xe768775c'89ac8b70'94a339d5'6a55ab4a_u128},
+ {Sign::POS, -136, 0xeb6c1eaf'd9dfa1eb'fa9998fb'f9703bf4_u128},
+ {Sign::POS, -136, 0xef6fd620'b2b7a503'cafdc272'27b71eaa_u128},
+ {Sign::POS, -136, 0xf3739daf'959aaafc'688d4282'f6026aa3_u128},
+ {Sign::POS, -136, 0xf777755d'03f4e0b6'e54e9e38'04464cdd_u128},
+ {Sign::POS, -136, 0xfb7b5d29'7f388a12'cb78b383'f4b59dce_u128},
+ {Sign::POS, -136, 0xff7f5515'88de024f'ee055fc5'15062c04_u128},
+ {Sign::POS, -135, 0x81c1ae90'd131de38'207812b4'3382acdd_u128},
+ {Sign::POS, -135, 0x83c3baa7'26a721cc'dc90c4c4'b61f3a87_u128},
+ {Sign::POS, -135, 0x85c5cece'05941dbc'1a03f13f'b2c978b1_u128},
+ {Sign::POS, -135, 0x87c7eb05'aec1304f'b36f282e'83a7dc36_u128},
+ {Sign::POS, -135, 0x89ca0f4e'62f9c476'6ad14c3d'fa414391_u128},
+ {Sign::POS, -135, 0x8bcc3ba8'630c51f4'e8dd4ea0'd48b88e5_u128},
+ {Sign::POS, -135, 0x8dce7013'efca5d96'c02515af'e8caeb90_u128},
+ {Sign::POS, -135, 0x8fd0ac91'4a08795f'741ceaf3'349f3cf1_u128},
+ {Sign::POS, -135, 0x91d2f120'b29e44bb'83f7cd49'29d2c28c_u128},
+ {Sign::POS, -135, 0x93d53dc2'6a666cb1'795d03eb'c2fd03fa_u128},
+ {Sign::POS, -135, 0x95d79276'b23eac12'faf74f1d'1ad16acc_u128},
+ {Sign::POS, -135, 0x97d9ef3d'cb07cbad'e2de134f'72fee429_u128},
+ {Sign::POS, -135, 0x99dc5417'f5a5a27d'58d8dba6'cadac5d5_u128},
+ {Sign::POS, -135, 0x9bdec105'72ff15da'f07d90bc'5aae40a4_u128},
+ {Sign::POS, -135, 0x9d609804'6659ea6b'1deaf79d'9fc40374_u128},
+ {Sign::POS, -135, 0x9f631314'50b07988'7ba63e67'69b81999_u128},
+ {Sign::POS, -135, 0xa1659638'404d5f92'59ebfc93'35094e59_u128},
+ {Sign::POS, -135, 0xa3682170'7622f97a'16aae012'b5026f71_u128},
+ {Sign::POS, -135, 0xa56ab4bd'3326b378'ff5d4f2c'0e4b9cae_u128},
+ {Sign::POS, -135, 0xa76d501e'b8510941'855838b5'119dcb28_u128},
+ {Sign::POS, -135, 0xa96ff395'469d8630'75f70cbb'e9cf1603_u128},
+ {Sign::POS, -135, 0xab729f21'1f0ac57e'36a53ad4'd5541cc9_u128},
+ {Sign::POS, -135, 0xad7552c2'829a7270'04c5934e'c32d20d9_u128},
+ {Sign::POS, -135, 0xaf780e79'b2514889'3977e89a'ec59bfa2_u128},
+ {Sign::POS, -135, 0xb17ad246'ef3713bc'913d4e3d'c55c3e6e_u128},
+ {Sign::POS, -135, 0xb37d9e2a'7a56b09d'777b52a9'e70d8bcc_u128},
+ {Sign::POS, -135, 0xb5807224'94be0c91'55de916f'd30591de_u128},
+ {Sign::POS, -135, 0xb7834e35'7f7e2600'e79cfb37'be2861e4_u128},
+ {Sign::POS, -135, 0xb986325d'7bab0c89'90983104'd3805389_u128},
+ {Sign::POS, -135, 0xbb891e9c'ca5be12e'b860504b'aa6f984d_u128},
+ {Sign::POS, -135, 0xbd8c12f3'acaad68b'29178d6f'f5712b96_u128},
+ {Sign::POS, -135, 0xbf8f0f62'63b53102'7236fa47'ba19a198_u128},
+ {Sign::POS, -135, 0xc19213e9'309b46f2'4f34d64c'afcc50e3_u128},
+ {Sign::POS, -135, 0xc3952088'548080e4'120cc62e'b0a8db3e_u128},
+ {Sign::POS, -135, 0xc5983540'108b59be'11aa5084'779060e3_u128},
+ {Sign::POS, -135, 0xc79b5210'a5e55ef5'1c35fd62'36c8dcf1_u128},
+ {Sign::POS, -135, 0xc99e76fa'55bb30bd'ed4576a7'e4b878fe_u128},
+ {Sign::POS, -135, 0xcb20d7fa'3a336081'6caf4bb8'fd2c1131_u128},
+ {Sign::POS, -135, 0xcd240b10'753e78de'3f24a6cb'b09c654f_u128},
+ {Sign::POS, -135, 0xcf274640'7e0ff09f'78bc003b'b81e40f3_u128},
+ {Sign::POS, -135, 0xd12a898a'95dff002'56647301'edfd8e8b_u128},
+ {Sign::POS, -135, 0xd32dd4ee'fde9b2ef'28fe1c4d'04ca4ed9_u128},
+ {Sign::POS, -135, 0xd531286d'f76b892a'e1ea9ea6'cbf57379_u128},
+ {Sign::POS, -135, 0xd7348407'c3a6d688'a3832028'141a5cc2_u128},
+ {Sign::POS, -135, 0xd937e7bc'a3e0131b'557421dd'379d3ead_u128},
+ {Sign::POS, -135, 0xdb3b538c'd95ecb67'3cff8e87'a99bcaf0_u128},
+ {Sign::POS, -135, 0xdd3ec778'a56da093'99255ef3'4bd0801f_u128},
+ {Sign::POS, -135, 0xdf424380'495a489c'42b33220'abfa15cd_u128},
+ {Sign::POS, -135, 0xe145c7a4'06758e83'503b378f'aa97dbc0_u128},
+ {Sign::POS, -135, 0xe34953e4'1e135282'bdf2ca00'6f59b544_u128},
+ {Sign::POS, -135, 0xe54ce840'd18a8a3e'1979190a'f37ed16f_u128},
+ {Sign::POS, -135, 0xe75084ba'623540f4'31863ff7'cf898c9c_u128},
+ {Sign::POS, -135, 0xe9542951'117097b0'c983284f'60293647_u128},
+ {Sign::POS, -135, 0xeb57d605'209cc57e'510a969e'be03f804_u128},
+ {Sign::POS, -135, 0xed5b8ad6'd11d1797'9f53bffc'6d23fe30_u128},
+ {Sign::POS, -135, 0xef5f47c6'6457f199'b286c6e1'13337886_u128},
+ {Sign::POS, -135, 0xf0e21acd'd6e7d412'b6ed8085'2ae6fd63_u128},
+ {Sign::POS, -135, 0xf2e5e5f2'5450c5a2'df437fb0'f616082d_u128},
+ {Sign::POS, -135, 0xf4e9b935'685dbe0b'f237cff1'acb306b3_u128},
+ {Sign::POS, -135, 0xf6ed9497'5480b696'52dbfafb'4121a092_u128},
+ {Sign::POS, -135, 0xf8f17818'5a2ebfd9'0d816482'49cece4c_u128},
+ {Sign::POS, -135, 0xfaf563b8'bae001eb'ad95e6b0'b96903d3_u128},
+ {Sign::POS, -135, 0xfcf95778'b80fbc98'176cd568'87ac7fe9_u128},
+ {Sign::POS, -135, 0xfefd5358'933c478c'65f4c739'7f1f478d_u128},
},
// -log(r) for the third step, generated by SageMath with:
//
@@ -388,170 +391,170 @@ alignas(64) const LogRR LOG_TABLE = {
// r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
// print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_3 = */
{
- {Sign::NEG, -142, MType({0x374b294076d669c3, 0x9fff38014d52e45a})},
- {Sign::NEG, -142, MType({0x7f6f05dcdbeb776e, 0x9dff3cf940fad85a})},
- {Sign::NEG, -142, MType({0x3d55e21d41bbadf9, 0x9bff41e134f1cb36})},
- {Sign::NEG, -142, MType({0xccdba2d54aadbc5c, 0x99ff46b92936bcf4})},
- {Sign::NEG, -142, MType({0x71dd16d3073f79b2, 0x97ff4b811dc8ad9d})},
- {Sign::NEG, -142, MType({0x5837f3df1a58dd48, 0x95ff503912a69d37})},
- {Sign::NEG, -142, MType({0x93cad3bcdd26fd6d, 0x93ff54e107cf8bc9})},
- {Sign::NEG, -142, MType({0x2075312a827f14fa, 0x91ff5978fd42795b})},
- {Sign::NEG, -142, MType({0xe21764e139c98f60, 0x8fff5e00f2fe65f2})},
- {Sign::NEG, -142, MType({0xa492a29551751b4c, 0x8dff6278e9025197})},
- {Sign::NEG, -142, MType({0x1bc8f5f658f1c3a2, 0x8bff66e0df4d3c50})},
- {Sign::NEG, -142, MType({0xe39d3faf42340ed7, 0x89ff6b38d5de2622})},
- {Sign::NEG, -142, MType({0x7ff3326682c02485, 0x87ff6f80ccb40f16})},
- {Sign::NEG, -142, MType({0x5caf4fbe343cf928, 0x85ff73b8c3cdf731})},
- {Sign::NEG, -142, MType({0xcdb6e554348f7fe8, 0x83ff77e0bb2ade79})},
- {Sign::NEG, -142, MType({0xef009c2457de25d, 0x81ff7bf8b2c9c4f6})},
- {Sign::NEG, -143, MType({0x8883333c57b57c74, 0xffff000155535558})},
- {Sign::NEG, -143, MType({0xf32668f39c70d183, 0xfbff07f145931f44})},
- {Sign::NEG, -143, MType({0x459a73c6a6486fe3, 0xf7ff0fc13650e7bd})},
- {Sign::NEG, -143, MType({0x37b18cca7dd3a29f, 0xf3ff1771278aaecd})},
- {Sign::NEG, -143, MType({0x513f610d21bcfc78, 0xefff1f01193e7480})},
- {Sign::NEG, -143, MType({0xea190b95c0690b7b, 0xebff26710b6a38e1})},
- {Sign::NEG, -143, MType({0x2a150f64f0ad1743, 0xe7ff2dc0fe0bfbfd})},
- {Sign::NEG, -143, MType({0x90b5174e995e9d1, 0xe3ff34f0f121bddd})},
- {Sign::NEG, -143, MType({0x4ed512b9b93ea2bf, 0xdfff3c00e4a97e8c})},
- {Sign::NEG, -143, MType({0x934cea217ab794a2, 0xdbff42f0d8a13e15})},
- {Sign::NEG, -143, MType({0x3e4ebe948afd2c76, 0xd7ff49c0cd06fc83})},
- {Sign::NEG, -143, MType({0x87b7c0f5bcfee2e1, 0xd3ff5070c1d8b9df})},
- {Sign::NEG, -143, MType({0x776666228cb6371b, 0xcfff5700b7147634})},
- {Sign::NEG, -143, MType({0xe53a60f3514db358, 0xcbff5d70acb8318b})},
- {Sign::NEG, -143, MType({0x79149c3b6e57fa86, 0xc7ff63c0a2c1ebef})},
- {Sign::NEG, -143, MType({0xaad734c98416df2a, 0xc3ff69f0992fa568})},
- {Sign::NEG, -143, MType({0xc26573679ed28334, 0xbfff70008fff5e00})},
- {Sign::NEG, -143, MType({0xd7a3c6db6540809f, 0xbbff75f0872f15c0})},
- {Sign::NEG, -143, MType({0xd277bde645fb1aad, 0xb7ff7bc07ebcccb1})},
- {Sign::NEG, -143, MType({0x6ac80145a4087793, 0xb3ff817076a682dc})},
- {Sign::NEG, -143, MType({0x287c4db30271e265, 0xafff87006eea3849})},
- {Sign::NEG, -143, MType({0x637d6de42eeb151e, 0xabff8c706785ed00})},
- {Sign::NEG, -143, MType({0x43b5348b6b898a8c, 0xa7ff91c06077a10a})},
- {Sign::NEG, -143, MType({0xc10e7657978bd7f6, 0xa3ff96f059bd546e})},
- {Sign::NEG, -143, MType({0xa37503f457310e59, 0x9fff9c0053550735})},
- {Sign::NEG, -143, MType({0x82d5a40a3aa022ff, 0x9bffa0f04d3cb966})},
- {Sign::NEG, -143, MType({0xc71e0d3ee3df5f4d, 0x97ffa5c047726b08})},
- {Sign::NEG, -143, MType({0xa83ce0352bdbd79b, 0x93ffaa7041f41c23})},
- {Sign::NEG, -143, MType({0x2e21a18d4680e8e4, 0x8fffaf003cbfccbe})},
- {Sign::NEG, -143, MType({0x30bcb3e4e5dfbd28, 0x8bffb37037d37cdf})},
- {Sign::NEG, -143, MType({0x57ff51d75c66d64a, 0x87ffb7c0332d2c8d})},
- {Sign::NEG, -143, MType({0x1bdb87fdbe299f43, 0x83ffbbf02ecadbcf})},
- {Sign::NEG, -144, MType({0x88885dde02700703, 0xffff800055551555})},
- {Sign::NEG, -144, MType({0xd259ca803a0c1870, 0xf7ff87e04d94724c})},
- {Sign::NEG, -144, MType({0xe514130851c7070a, 0xefff8f80464fce8f})},
- {Sign::NEG, -144, MType({0x30a16898f3073a64, 0xe7ff96e03f832a2a})},
- {Sign::NEG, -144, MType({0xc4ed64517b2949ce, 0xdfff9e00392a8526})},
- {Sign::NEG, -144, MType({0x51e4fb4e32cf6350, 0xd7ffa4e03341df90})},
- {Sign::NEG, -144, MType({0x277672a88350bcce, 0xcfffab802dc53971})},
- {Sign::NEG, -144, MType({0x359153772a490f06, 0xc7ffb1e028b092d3})},
- {Sign::NEG, -144, MType({0xc265ece6b481a0e, 0xbfffb80023ffebc0})},
- {Sign::NEG, -144, MType({0xdb2781c03fa132f6, 0xb7ffbde01faf4440})},
- {Sign::NEG, -144, MType({0x7287c95c845ada33, 0xafffc3801bba9c5e})},
- {Sign::NEG, -144, MType({0x423b56b1263e5a77, 0xa7ffc8e0181df421})},
- {Sign::NEG, -144, MType({0x5a3752ca4c076fa3, 0x9fffce0014d54b91})},
- {Sign::NEG, -144, MType({0x6a71e2b27eb3f573, 0x97ffd2e011dca2b6})},
- {Sign::NEG, -144, MType({0xc2e21b72cff39d8f, 0x8fffd7800f2ff997})},
- {Sign::NEG, -144, MType({0x537ff612feb7ac9e, 0x87ffdbe00ccb503c})},
- {Sign::NEG, -145, MType({0x5888873333c57c18, 0xffffc00015554d55})},
- {Sign::NEG, -145, MType({0xfa51421842311c42, 0xefffc7c01193f9d1})},
- {Sign::NEG, -145, MType({0x2c4ed6de475b942c, 0xdfffcf000e4aa5fa})},
- {Sign::NEG, -145, MType({0xce77678cbb6fcb88, 0xcfffd5c00b7151d8})},
- {Sign::NEG, -145, MType({0xc26629a679ed3b, 0xbfffdc0008fffd78})},
- {Sign::NEG, -145, MType({0x23287cb9d3072728, 0xafffe1c006eea8e1})},
- {Sign::NEG, -145, MType({0xd5a37540fd057315, 0x9fffe7000535541c})},
- {Sign::NEG, -145, MType({0xf82e21c1fce36810, 0x8fffebc003cbff32})},
- {Sign::NEG, -146, MType({0x5588887ddde02702, 0xffffe00005555455})},
- {Sign::NEG, -146, MType({0x9ac4ed72adf5b295, 0xdfffe7800392aa14})},
- {Sign::NEG, -146, MType({0xc26648066b482, 0xbfffee00023fffaf})},
- {Sign::NEG, -146, MType({0x455a3754b292c077, 0x9ffff380014d552e})},
- {Sign::NEG, -147, MType({0x5558888833333c58, 0xfffff00001555535})},
- {Sign::NEG, -147, MType({0xe000c2665736679f, 0xbffff700008ffff5})},
- {Sign::NEG, -148, MType({0x5555888885ddde02, 0xfffff80000555551})},
- {Sign::NEG, -149, MType({0xd555588888733334, 0xfffffc0000155554})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -148, MType({0xeaaaac44444eeeef, 0x80000200000aaaaa})},
- {Sign::POS, -147, MType({0xaaaac444459999ac, 0x80000400002aaaac})},
- {Sign::POS, -147, MType({0x2000c2667596679f, 0xc00009000090000a})},
- {Sign::POS, -146, MType({0xaaac44446eeef381, 0x8000080000aaaaba})},
- {Sign::POS, -146, MType({0x655a3755f81815cc, 0xa0000c80014d557c})},
- {Sign::POS, -146, MType({0xc26684c66b482, 0xc000120002400051})},
- {Sign::POS, -146, MType({0xbac4ed7c40fb07eb, 0xe00018800392ab40})},
- {Sign::POS, -145, MType({0xaac44449999abe2c, 0x8000100002aaab2a})},
- {Sign::POS, -145, MType({0x82e21d79cbb6812, 0x9000144003cc00cd})},
- {Sign::POS, -145, MType({0xd5a37569adb01dc3, 0xa00019000535568d})},
- {Sign::POS, -145, MType({0x33287d01e8c9d1d9, 0xb0001e4006eeac74})},
- {Sign::POS, -145, MType({0xc266a32679ed48, 0xc000240009000288})},
- {Sign::POS, -145, MType({0xde77685122b2764b, 0xd0002a400b7158d1})},
- {Sign::POS, -145, MType({0x2c4ed810a8063f03, 0xe00031000e4aaf5b})},
- {Sign::POS, -145, MType({0xa5143e7be891c8f, 0xf00038401194062e})},
- {Sign::POS, -144, MType({0xac4444eeef3813a1, 0x800020000aaaaeaa})},
- {Sign::POS, -144, MType({0x5b7ff7fe1339025b, 0x880024200ccb5a6e})},
- {Sign::POS, -144, MType({0x42e21e26caf39e33, 0x900028800f300668})},
- {Sign::POS, -144, MType({0xf271e66fa5554bc6, 0x98002d2011dcb29e})},
- {Sign::POS, -144, MType({0x5a3757e0615cc676, 0xa000320014d55f19})},
- {Sign::POS, -144, MType({0xca3b5d8210ca5cab, 0xa8003720181e0bde})},
- {Sign::POS, -144, MType({0xf287d25f3cb032bb, 0xb0003c801bbab8f6})},
- {Sign::POS, -144, MType({0xe3278d840be28cdb, 0xb80042201faf6669})},
- {Sign::POS, -144, MType({0xc266dfe6b482076, 0xc000480024001440})},
- {Sign::POS, -144, MType({0x3d9166de380a6d3d, 0xc8004e2028b0c282})},
- {Sign::POS, -144, MType({0xa7768b356ba61e4b, 0xd00054802dc57139})},
- {Sign::POS, -144, MType({0xd9e51a1849db73c1, 0xd8005b203342206f})},
- {Sign::POS, -144, MType({0xc4ed8a9d907eb521, 0xe0006200392ad02e})},
- {Sign::POS, -144, MType({0xb8a197dea928acd7, 0xe80069203f838080})},
- {Sign::POS, -144, MType({0x65144cf7dcc72d3b, 0xf000708046503170})},
- {Sign::POS, -144, MType({0xda5a1108890d9f6a, 0xf80078204d94e308})},
- {Sign::POS, -143, MType({0xc4445999abe2ce2c, 0x800040002aaacaaa})},
- {Sign::POS, -143, MType({0x1fdbbb4f3bffc832, 0x840044102ecb2431})},
- {Sign::POS, -143, MType({0x97ff8f39ec91b4ee, 0x88004840332d7e1d})},
- {Sign::POS, -143, MType({0x74bcfcf0b3f0a95d, 0x8c004c9037d3d876})},
- {Sign::POS, -143, MType({0x2e21f80ca6813aff, 0x900051003cc03342})},
- {Sign::POS, -143, MType({0x6c3d4629170ce87f, 0x9400559041f48e87})},
- {Sign::POS, -143, MType({0x71e84e3b80a8881, 0x98005a404772ea4d})},
- {Sign::POS, -143, MType({0x6d62fdcbdd6bec3, 0x9c005f104d3d469a})},
- {Sign::POS, -143, MType({0xa375a6b701dc77c0, 0xa00064005355a375})},
- {Sign::POS, -143, MType({0x450f331826ad6b05, 0xa400691059be00e7})},
- {Sign::POS, -143, MType({0x83b60ea8bd0aa459, 0xa8006e4060785ef6})},
- {Sign::POS, -143, MType({0x277e691469dd13f5, 0xac0073906786bdab})},
- {Sign::POS, -143, MType({0x287d6e0a0d1e25eb, 0xb00079006eeb1d0d})},
- {Sign::POS, -143, MType({0xaec94b3be9b060f5, 0xb4007e9076a77d24})},
- {Sign::POS, -143, MType({0x1279365fce280cce, 0xb80084407ebdddfa})},
- {Sign::POS, -143, MType({0xdba5732f3e83e04a, 0xbc008a1087303f95})},
- {Sign::POS, -143, MType({0xc26759679ed5b754, 0xc00090009000a200})},
- {Sign::POS, -143, MType({0xaed95aca5edb5109, 0xc400961099310543})},
- {Sign::POS, -143, MType({0xb917091d2687160f, 0xc8009c40a2c36967})},
- {Sign::POS, -143, MType({0x293d1c2a0378e75d, 0xcc00a290acb9ce76})},
- {Sign::POS, -143, MType({0x776977bf9766f5a7, 0xd000a900b7163478})},
- {Sign::POS, -143, MType({0x4bbb31b14776a18b, 0xd400af90c1da9b78})},
- {Sign::POS, -143, MType({0x7e5297d76c8564ba, 0xd800b640cd09037f})},
- {Sign::POS, -143, MType({0x1751360f8461c447, 0xdc00bd10d8a36c98})},
- {Sign::POS, -143, MType({0x4ed9dc3c63f44c41, 0xe000c400e4abd6cc})},
- {Sign::POS, -143, MType({0x8d10a4466a5894d5, 0xe400cb10f1244226})},
- {Sign::POS, -143, MType({0x6a1af81bb4e6510e, 0xe800d240fe0eaeb1})},
- {Sign::POS, -143, MType({0xae1f97b0542a677a, 0xec00d9910b6d1c77})},
- {Sign::POS, -143, MType({0x51469efe81d014cc, 0xf000e10119418b84})},
- {Sign::POS, -143, MType({0x7bb98c06d77a18b4, 0xf400e891278dfbe2})},
- {Sign::POS, -143, MType({0x85a344d0868bed17, 0xf800f04136546d9d})},
- {Sign::POS, -143, MType({0xf7301d6990e307cc, 0xfc00f8114596e0c0})},
- {Sign::POS, -142, MType({0x4446eef38140138f, 0x80008000aaabaaac})},
- {Sign::POS, -142, MType({0x10f5e43296105497, 0x82008408b2cbe5b8})},
- {Sign::POS, -142, MType({0xedbd4f83ef63f730, 0x84008820bb2d2189})},
- {Sign::POS, -142, MType({0xfeb654fd541c638e, 0x86008c48c3d05e27})},
- {Sign::POS, -142, MType({0x7ffadeb8882f7674, 0x88009080ccb69b98})},
- {Sign::POS, -142, MType({0xc5a59fd36bd44397, 0x8a0094c8d5e0d9e1})},
- {Sign::POS, -142, MType({0x3bd217701b27dddb, 0x8c009920df50190a})},
- {Sign::POS, -142, MType({0x669c93b50e4a2595, 0x8e009d88e9055918})},
- {Sign::POS, -142, MType({0xe22234cd39f29cd4, 0x9000a200f3019a12})},
- {Sign::POS, -142, MType({0x6280efe8307d41d9, 0x9200a688fd45dc00})},
- {Sign::POS, -142, MType({0xb3d7923a436f6fc4, 0x9400ab2107d31ee7})},
- {Sign::POS, -142, MType({0xba45c3fca574c5a0, 0x9600afc912aa62cf})},
- {Sign::POS, -142, MType({0x71ec0b6d8cd413d1, 0x9800b4811dcca7bf})},
- {Sign::POS, -142, MType({0xeeebcfd0565c5006, 0x9a00b949293aedbd})},
- {Sign::POS, -142, MType({0x5d675c6da8c98fc3, 0x9c00be2134f634d2})},
- {Sign::POS, -142, MType({0x181e39398a2099a, 0x9e00c30940ff7d04})},
- {Sign::POS, -142, MType({0x375f8195cc8b1d29, 0xa000c8014d57c65a})},
+ {Sign::NEG, -142, 0x9fff3801'4d52e45a'374b2940'76d669c3_u128},
+ {Sign::NEG, -142, 0x9dff3cf9'40fad85a'7f6f05dc'dbeb776e_u128},
+ {Sign::NEG, -142, 0x9bff41e1'34f1cb36'3d55e21d'41bbadf9_u128},
+ {Sign::NEG, -142, 0x99ff46b9'2936bcf4'ccdba2d5'4aadbc5c_u128},
+ {Sign::NEG, -142, 0x97ff4b81'1dc8ad9d'71dd16d3'073f79b2_u128},
+ {Sign::NEG, -142, 0x95ff5039'12a69d37'5837f3df'1a58dd48_u128},
+ {Sign::NEG, -142, 0x93ff54e1'07cf8bc9'93cad3bc'dd26fd6d_u128},
+ {Sign::NEG, -142, 0x91ff5978'fd42795b'2075312a'827f14fa_u128},
+ {Sign::NEG, -142, 0x8fff5e00'f2fe65f2'e21764e1'39c98f60_u128},
+ {Sign::NEG, -142, 0x8dff6278'e9025197'a492a295'51751b4c_u128},
+ {Sign::NEG, -142, 0x8bff66e0'df4d3c50'1bc8f5f6'58f1c3a2_u128},
+ {Sign::NEG, -142, 0x89ff6b38'd5de2622'e39d3faf'42340ed7_u128},
+ {Sign::NEG, -142, 0x87ff6f80'ccb40f16'7ff33266'82c02485_u128},
+ {Sign::NEG, -142, 0x85ff73b8'c3cdf731'5caf4fbe'343cf928_u128},
+ {Sign::NEG, -142, 0x83ff77e0'bb2ade79'cdb6e554'348f7fe8_u128},
+ {Sign::NEG, -142, 0x81ff7bf8'b2c9c4f6'0ef009c2'457de25d_u128},
+ {Sign::NEG, -143, 0xffff0001'55535558'8883333c'57b57c74_u128},
+ {Sign::NEG, -143, 0xfbff07f1'45931f44'f32668f3'9c70d183_u128},
+ {Sign::NEG, -143, 0xf7ff0fc1'3650e7bd'459a73c6'a6486fe3_u128},
+ {Sign::NEG, -143, 0xf3ff1771'278aaecd'37b18cca'7dd3a29f_u128},
+ {Sign::NEG, -143, 0xefff1f01'193e7480'513f610d'21bcfc78_u128},
+ {Sign::NEG, -143, 0xebff2671'0b6a38e1'ea190b95'c0690b7b_u128},
+ {Sign::NEG, -143, 0xe7ff2dc0'fe0bfbfd'2a150f64'f0ad1743_u128},
+ {Sign::NEG, -143, 0xe3ff34f0'f121bddd'090b5174'e995e9d1_u128},
+ {Sign::NEG, -143, 0xdfff3c00'e4a97e8c'4ed512b9'b93ea2bf_u128},
+ {Sign::NEG, -143, 0xdbff42f0'd8a13e15'934cea21'7ab794a2_u128},
+ {Sign::NEG, -143, 0xd7ff49c0'cd06fc83'3e4ebe94'8afd2c76_u128},
+ {Sign::NEG, -143, 0xd3ff5070'c1d8b9df'87b7c0f5'bcfee2e1_u128},
+ {Sign::NEG, -143, 0xcfff5700'b7147634'77666622'8cb6371b_u128},
+ {Sign::NEG, -143, 0xcbff5d70'acb8318b'e53a60f3'514db358_u128},
+ {Sign::NEG, -143, 0xc7ff63c0'a2c1ebef'79149c3b'6e57fa86_u128},
+ {Sign::NEG, -143, 0xc3ff69f0'992fa568'aad734c9'8416df2a_u128},
+ {Sign::NEG, -143, 0xbfff7000'8fff5e00'c2657367'9ed28334_u128},
+ {Sign::NEG, -143, 0xbbff75f0'872f15c0'd7a3c6db'6540809f_u128},
+ {Sign::NEG, -143, 0xb7ff7bc0'7ebcccb1'd277bde6'45fb1aad_u128},
+ {Sign::NEG, -143, 0xb3ff8170'76a682dc'6ac80145'a4087793_u128},
+ {Sign::NEG, -143, 0xafff8700'6eea3849'287c4db3'0271e265_u128},
+ {Sign::NEG, -143, 0xabff8c70'6785ed00'637d6de4'2eeb151e_u128},
+ {Sign::NEG, -143, 0xa7ff91c0'6077a10a'43b5348b'6b898a8c_u128},
+ {Sign::NEG, -143, 0xa3ff96f0'59bd546e'c10e7657'978bd7f6_u128},
+ {Sign::NEG, -143, 0x9fff9c00'53550735'a37503f4'57310e59_u128},
+ {Sign::NEG, -143, 0x9bffa0f0'4d3cb966'82d5a40a'3aa022ff_u128},
+ {Sign::NEG, -143, 0x97ffa5c0'47726b08'c71e0d3e'e3df5f4d_u128},
+ {Sign::NEG, -143, 0x93ffaa70'41f41c23'a83ce035'2bdbd79b_u128},
+ {Sign::NEG, -143, 0x8fffaf00'3cbfccbe'2e21a18d'4680e8e4_u128},
+ {Sign::NEG, -143, 0x8bffb370'37d37cdf'30bcb3e4'e5dfbd28_u128},
+ {Sign::NEG, -143, 0x87ffb7c0'332d2c8d'57ff51d7'5c66d64a_u128},
+ {Sign::NEG, -143, 0x83ffbbf0'2ecadbcf'1bdb87fd'be299f43_u128},
+ {Sign::NEG, -144, 0xffff8000'55551555'88885dde'02700703_u128},
+ {Sign::NEG, -144, 0xf7ff87e0'4d94724c'd259ca80'3a0c1870_u128},
+ {Sign::NEG, -144, 0xefff8f80'464fce8f'e5141308'51c7070a_u128},
+ {Sign::NEG, -144, 0xe7ff96e0'3f832a2a'30a16898'f3073a64_u128},
+ {Sign::NEG, -144, 0xdfff9e00'392a8526'c4ed6451'7b2949ce_u128},
+ {Sign::NEG, -144, 0xd7ffa4e0'3341df90'51e4fb4e'32cf6350_u128},
+ {Sign::NEG, -144, 0xcfffab80'2dc53971'277672a8'8350bcce_u128},
+ {Sign::NEG, -144, 0xc7ffb1e0'28b092d3'35915377'2a490f06_u128},
+ {Sign::NEG, -144, 0xbfffb800'23ffebc0'0c265ece'6b481a0e_u128},
+ {Sign::NEG, -144, 0xb7ffbde0'1faf4440'db2781c0'3fa132f6_u128},
+ {Sign::NEG, -144, 0xafffc380'1bba9c5e'7287c95c'845ada33_u128},
+ {Sign::NEG, -144, 0xa7ffc8e0'181df421'423b56b1'263e5a77_u128},
+ {Sign::NEG, -144, 0x9fffce00'14d54b91'5a3752ca'4c076fa3_u128},
+ {Sign::NEG, -144, 0x97ffd2e0'11dca2b6'6a71e2b2'7eb3f573_u128},
+ {Sign::NEG, -144, 0x8fffd780'0f2ff997'c2e21b72'cff39d8f_u128},
+ {Sign::NEG, -144, 0x87ffdbe0'0ccb503c'537ff612'feb7ac9e_u128},
+ {Sign::NEG, -145, 0xffffc000'15554d55'58888733'33c57c18_u128},
+ {Sign::NEG, -145, 0xefffc7c0'1193f9d1'fa514218'42311c42_u128},
+ {Sign::NEG, -145, 0xdfffcf00'0e4aa5fa'2c4ed6de'475b942c_u128},
+ {Sign::NEG, -145, 0xcfffd5c0'0b7151d8'ce77678c'bb6fcb88_u128},
+ {Sign::NEG, -145, 0xbfffdc00'08fffd78'00c26629'a679ed3b_u128},
+ {Sign::NEG, -145, 0xafffe1c0'06eea8e1'23287cb9'd3072728_u128},
+ {Sign::NEG, -145, 0x9fffe700'0535541c'd5a37540'fd057315_u128},
+ {Sign::NEG, -145, 0x8fffebc0'03cbff32'f82e21c1'fce36810_u128},
+ {Sign::NEG, -146, 0xffffe000'05555455'5588887d'dde02702_u128},
+ {Sign::NEG, -146, 0xdfffe780'0392aa14'9ac4ed72'adf5b295_u128},
+ {Sign::NEG, -146, 0xbfffee00'023fffaf'000c2664'8066b482_u128},
+ {Sign::NEG, -146, 0x9ffff380'014d552e'455a3754'b292c077_u128},
+ {Sign::NEG, -147, 0xfffff000'01555535'55588888'33333c58_u128},
+ {Sign::NEG, -147, 0xbffff700'008ffff5'e000c266'5736679f_u128},
+ {Sign::NEG, -148, 0xfffff800'00555551'55558888'85ddde02_u128},
+ {Sign::NEG, -149, 0xfffffc00'00155554'd5555888'88733334_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -148, 0x80000200'000aaaaa'eaaaac44'444eeeef_u128},
+ {Sign::POS, -147, 0x80000400'002aaaac'aaaac444'459999ac_u128},
+ {Sign::POS, -147, 0xc0000900'0090000a'2000c266'7596679f_u128},
+ {Sign::POS, -146, 0x80000800'00aaaaba'aaac4444'6eeef381_u128},
+ {Sign::POS, -146, 0xa0000c80'014d557c'655a3755'f81815cc_u128},
+ {Sign::POS, -146, 0xc0001200'02400051'000c2668'4c66b482_u128},
+ {Sign::POS, -146, 0xe0001880'0392ab40'bac4ed7c'40fb07eb_u128},
+ {Sign::POS, -145, 0x80001000'02aaab2a'aac44449'999abe2c_u128},
+ {Sign::POS, -145, 0x90001440'03cc00cd'082e21d7'9cbb6812_u128},
+ {Sign::POS, -145, 0xa0001900'0535568d'd5a37569'adb01dc3_u128},
+ {Sign::POS, -145, 0xb0001e40'06eeac74'33287d01'e8c9d1d9_u128},
+ {Sign::POS, -145, 0xc0002400'09000288'00c266a3'2679ed48_u128},
+ {Sign::POS, -145, 0xd0002a40'0b7158d1'de776851'22b2764b_u128},
+ {Sign::POS, -145, 0xe0003100'0e4aaf5b'2c4ed810'a8063f03_u128},
+ {Sign::POS, -145, 0xf0003840'1194062e'0a5143e7'be891c8f_u128},
+ {Sign::POS, -144, 0x80002000'0aaaaeaa'ac4444ee'ef3813a1_u128},
+ {Sign::POS, -144, 0x88002420'0ccb5a6e'5b7ff7fe'1339025b_u128},
+ {Sign::POS, -144, 0x90002880'0f300668'42e21e26'caf39e33_u128},
+ {Sign::POS, -144, 0x98002d20'11dcb29e'f271e66f'a5554bc6_u128},
+ {Sign::POS, -144, 0xa0003200'14d55f19'5a3757e0'615cc676_u128},
+ {Sign::POS, -144, 0xa8003720'181e0bde'ca3b5d82'10ca5cab_u128},
+ {Sign::POS, -144, 0xb0003c80'1bbab8f6'f287d25f'3cb032bb_u128},
+ {Sign::POS, -144, 0xb8004220'1faf6669'e3278d84'0be28cdb_u128},
+ {Sign::POS, -144, 0xc0004800'24001440'0c266dfe'6b482076_u128},
+ {Sign::POS, -144, 0xc8004e20'28b0c282'3d9166de'380a6d3d_u128},
+ {Sign::POS, -144, 0xd0005480'2dc57139'a7768b35'6ba61e4b_u128},
+ {Sign::POS, -144, 0xd8005b20'3342206f'd9e51a18'49db73c1_u128},
+ {Sign::POS, -144, 0xe0006200'392ad02e'c4ed8a9d'907eb521_u128},
+ {Sign::POS, -144, 0xe8006920'3f838080'b8a197de'a928acd7_u128},
+ {Sign::POS, -144, 0xf0007080'46503170'65144cf7'dcc72d3b_u128},
+ {Sign::POS, -144, 0xf8007820'4d94e308'da5a1108'890d9f6a_u128},
+ {Sign::POS, -143, 0x80004000'2aaacaaa'c4445999'abe2ce2c_u128},
+ {Sign::POS, -143, 0x84004410'2ecb2431'1fdbbb4f'3bffc832_u128},
+ {Sign::POS, -143, 0x88004840'332d7e1d'97ff8f39'ec91b4ee_u128},
+ {Sign::POS, -143, 0x8c004c90'37d3d876'74bcfcf0'b3f0a95d_u128},
+ {Sign::POS, -143, 0x90005100'3cc03342'2e21f80c'a6813aff_u128},
+ {Sign::POS, -143, 0x94005590'41f48e87'6c3d4629'170ce87f_u128},
+ {Sign::POS, -143, 0x98005a40'4772ea4d'071e84e3'b80a8881_u128},
+ {Sign::POS, -143, 0x9c005f10'4d3d469a'06d62fdc'bdd6bec3_u128},
+ {Sign::POS, -143, 0xa0006400'5355a375'a375a6b7'01dc77c0_u128},
+ {Sign::POS, -143, 0xa4006910'59be00e7'450f3318'26ad6b05_u128},
+ {Sign::POS, -143, 0xa8006e40'60785ef6'83b60ea8'bd0aa459_u128},
+ {Sign::POS, -143, 0xac007390'6786bdab'277e6914'69dd13f5_u128},
+ {Sign::POS, -143, 0xb0007900'6eeb1d0d'287d6e0a'0d1e25eb_u128},
+ {Sign::POS, -143, 0xb4007e90'76a77d24'aec94b3b'e9b060f5_u128},
+ {Sign::POS, -143, 0xb8008440'7ebdddfa'1279365f'ce280cce_u128},
+ {Sign::POS, -143, 0xbc008a10'87303f95'dba5732f'3e83e04a_u128},
+ {Sign::POS, -143, 0xc0009000'9000a200'c2675967'9ed5b754_u128},
+ {Sign::POS, -143, 0xc4009610'99310543'aed95aca'5edb5109_u128},
+ {Sign::POS, -143, 0xc8009c40'a2c36967'b917091d'2687160f_u128},
+ {Sign::POS, -143, 0xcc00a290'acb9ce76'293d1c2a'0378e75d_u128},
+ {Sign::POS, -143, 0xd000a900'b7163478'776977bf'9766f5a7_u128},
+ {Sign::POS, -143, 0xd400af90'c1da9b78'4bbb31b1'4776a18b_u128},
+ {Sign::POS, -143, 0xd800b640'cd09037f'7e5297d7'6c8564ba_u128},
+ {Sign::POS, -143, 0xdc00bd10'd8a36c98'1751360f'8461c447_u128},
+ {Sign::POS, -143, 0xe000c400'e4abd6cc'4ed9dc3c'63f44c41_u128},
+ {Sign::POS, -143, 0xe400cb10'f1244226'8d10a446'6a5894d5_u128},
+ {Sign::POS, -143, 0xe800d240'fe0eaeb1'6a1af81b'b4e6510e_u128},
+ {Sign::POS, -143, 0xec00d991'0b6d1c77'ae1f97b0'542a677a_u128},
+ {Sign::POS, -143, 0xf000e101'19418b84'51469efe'81d014cc_u128},
+ {Sign::POS, -143, 0xf400e891'278dfbe2'7bb98c06'd77a18b4_u128},
+ {Sign::POS, -143, 0xf800f041'36546d9d'85a344d0'868bed17_u128},
+ {Sign::POS, -143, 0xfc00f811'4596e0c0'f7301d69'90e307cc_u128},
+ {Sign::POS, -142, 0x80008000'aaabaaac'4446eef3'8140138f_u128},
+ {Sign::POS, -142, 0x82008408'b2cbe5b8'10f5e432'96105497_u128},
+ {Sign::POS, -142, 0x84008820'bb2d2189'edbd4f83'ef63f730_u128},
+ {Sign::POS, -142, 0x86008c48'c3d05e27'feb654fd'541c638e_u128},
+ {Sign::POS, -142, 0x88009080'ccb69b98'7ffadeb8'882f7674_u128},
+ {Sign::POS, -142, 0x8a0094c8'd5e0d9e1'c5a59fd3'6bd44397_u128},
+ {Sign::POS, -142, 0x8c009920'df50190a'3bd21770'1b27dddb_u128},
+ {Sign::POS, -142, 0x8e009d88'e9055918'669c93b5'0e4a2595_u128},
+ {Sign::POS, -142, 0x9000a200'f3019a12'e22234cd'39f29cd4_u128},
+ {Sign::POS, -142, 0x9200a688'fd45dc00'6280efe8'307d41d9_u128},
+ {Sign::POS, -142, 0x9400ab21'07d31ee7'b3d7923a'436f6fc4_u128},
+ {Sign::POS, -142, 0x9600afc9'12aa62cf'ba45c3fc'a574c5a0_u128},
+ {Sign::POS, -142, 0x9800b481'1dcca7bf'71ec0b6d'8cd413d1_u128},
+ {Sign::POS, -142, 0x9a00b949'293aedbd'eeebcfd0'565c5006_u128},
+ {Sign::POS, -142, 0x9c00be21'34f634d2'5d675c6d'a8c98fc3_u128},
+ {Sign::POS, -142, 0x9e00c309'40ff7d04'0181e393'98a2099a_u128},
+ {Sign::POS, -142, 0xa000c801'4d57c65a'375f8195'cc8b1d29_u128},
},
// -log(r) for the fourth step, generated by SageMath with:
@@ -560,139 +563,139 @@ alignas(64) const LogRR LOG_TABLE = {
// r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
// print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_4 = */
{
- {Sign::NEG, -149, MType({0x4cd24d68ff2f11ae, 0x81fffef7f002cb2b})},
- {Sign::NEG, -150, MType({0x455555888887ddde, 0xfffffe0000055555})},
- {Sign::NEG, -150, MType({0xf0fa101f52b3971f, 0xfbfffe0fe0051653})},
- {Sign::NEG, -150, MType({0x9c9329d659ed3734, 0xf7fffe1f8004d94a})},
- {Sign::NEG, -150, MType({0x4821006d9b58462e, 0xf3fffe2ee0049e31})},
- {Sign::NEG, -150, MType({0xf3a3f025142f8c21, 0xeffffe3e000464ff})},
- {Sign::NEG, -150, MType({0x9f1c53bcc1c4b11c, 0xebfffe4ce0042dae})},
- {Sign::NEG, -150, MType({0x4a8a8474a17fdd30, 0xe7fffe5b8003f835})},
- {Sign::NEG, -150, MType({0xf5eeda0cb0df586d, 0xe3fffe69e003c48b})},
- {Sign::NEG, -150, MType({0xa149aac4ed772adf, 0xdffffe78000392aa})},
- {Sign::NEG, -150, MType({0x4c9b4b5d54f0bc96, 0xdbfffe85e0036289})},
- {Sign::NEG, -150, MType({0xf7e40f15e50a759f, 0xd7fffe938003341f})},
- {Sign::NEG, -150, MType({0xa32447ae9b975e05, 0xd3fffea0e0030766})},
- {Sign::NEG, -150, MType({0x4e5c4567767ebdd5, 0xcffffeae0002dc55})},
- {Sign::NEG, -150, MType({0xf98c570073bbbd19, 0xcbfffebae002b2e3})},
- {Sign::NEG, -150, MType({0xa4b4c9b9915d03dd, 0xc7fffec780028b0a})},
- {Sign::NEG, -150, MType({0x4fd5e952cd845a28, 0xc3fffed3e00264c1})},
- {Sign::NEG, -150, MType({0xfaf0000c26664806, 0xbffffee000023fff})},
- {Sign::NEG, -150, MType({0xa60356a59a49b57f, 0xbbfffeebe0021cbe})},
- {Sign::NEG, -150, MType({0x5110345f27878a9b, 0xb7fffef78001faf5})},
- {Sign::NEG, -150, MType({0xfc16def8cc8a4f61, 0xb3ffff02e001da9b})},
- {Sign::NEG, -150, MType({0xa7179ab287cdcbd8, 0xafffff0e0001bbaa})},
- {Sign::NEG, -150, MType({0x5212aa4c57dea809, 0xabffff18e0019e19})},
- {Sign::NEG, -150, MType({0xfd084f063b5a0bf8, 0xa7ffff23800181df})},
- {Sign::NEG, -150, MType({0xa7f8c8a030ed3fab, 0xa3ffff2de00166f6})},
- {Sign::NEG, -150, MType({0x52e4555a37554b29, 0x9fffff3800014d55})},
- {Sign::NEG, -150, MType({0xfdcb31f44d5e9676, 0x9bffff41e00134f3})},
- {Sign::NEG, -150, MType({0xa8ad99ae71e48997, 0x97ffff4b80011dca})},
- {Sign::NEG, -150, MType({0x538bc648a3d12c90, 0x93ffff54e00107d1})},
- {Sign::NEG, -150, MType({0xfe65f002e21cc765, 0x8fffff5e0000f2ff})},
- {Sign::NEG, -150, MType({0xa93c4d9d2bcd821a, 0x8bffff66e000df4e})},
- {Sign::NEG, -150, MType({0x540f14577ff704b2, 0x87ffff6f8000ccb5})},
- {Sign::NEG, -150, MType({0xfede77f1ddba1731, 0x83ffff77e000bb2b})},
- {Sign::NEG, -151, MType({0x5355555888888333, 0xffffff0000015555})},
- {Sign::NEG, -151, MType({0xa8e7ba8d659ed7dc, 0xf7ffff0fc0013652})},
- {Sign::NEG, -151, MType({0xfe747e025142fc61, 0xefffff1f0001193f})},
- {Sign::NEG, -151, MType({0x53fbfb374a1800c7, 0xe7ffff2dc000fe0d})},
- {Sign::NEG, -151, MType({0xa97e8aac4ed77513, 0xdfffff3c0000e4aa})},
- {Sign::NEG, -151, MType({0xfefc81e15e50a947, 0xd7ffff49c000cd07})},
- {Sign::NEG, -151, MType({0x547633567767ed66, 0xcfffff570000b715})},
- {Sign::NEG, -151, MType({0xa9ebee8b9915d174, 0xc7ffff63c000a2c2})},
- {Sign::NEG, -151, MType({0xff5e0000c2666573, 0xbfffff7000008fff})},
- {Sign::NEG, -151, MType({0x54ccb135f2787966, 0xb7ffff7bc0007ebd})},
- {Sign::NEG, -151, MType({0xaa3848ab287cdd4e, 0xafffff8700006eea})},
- {Sign::NEG, -151, MType({0xffa109e063b5a12d, 0xa7ffff91c0006077})},
- {Sign::NEG, -151, MType({0x55073555a3755504, 0x9fffff9c00005355})},
- {Sign::NEG, -151, MType({0xaa6b088ae71e48d5, 0x97ffffa5c0004772})},
- {Sign::NEG, -151, MType({0xffccbe002e21cca2, 0x8fffffaf00003cbf})},
- {Sign::NEG, -151, MType({0x552c8d3577ff706a, 0x87ffffb7c000332d})},
- {Sign::NEG, -152, MType({0x551555558888885e, 0xffffff8000005555})},
- {Sign::NEG, -152, MType({0xffce8fc025142fe3, 0xefffff8f8000464f})},
- {Sign::NEG, -152, MType({0xaa8526aac4ed7764, 0xdfffff9e0000392a})},
- {Sign::NEG, -152, MType({0x5539711567767ee3, 0xcfffffab80002dc5})},
- {Sign::NEG, -152, MType({0xffebc0000c26665f, 0xbfffffb8000023ff})},
- {Sign::NEG, -152, MType({0xaa9c5e6ab287cdd9, 0xafffffc380001bba})},
- {Sign::NEG, -152, MType({0x554b91555a375553, 0x9fffffce000014d5})},
- {Sign::NEG, -152, MType({0xfff997c002e21ccb, 0x8fffffd780000f2f})},
- {Sign::NEG, -153, MType({0x554d555558888887, 0xffffffc000001555})},
- {Sign::NEG, -153, MType({0xaaa5fa2aac4ed777, 0xdfffffcf00000e4a})},
- {Sign::NEG, -153, MType({0xfffd780000c26666, 0xbfffffdc000008ff})},
- {Sign::NEG, -153, MType({0x55541cd555a37555, 0x9fffffe700000535})},
- {Sign::NEG, -154, MType({0x5554555555888888, 0xffffffe000000555})},
- {Sign::NEG, -154, MType({0xffffaf00000c2666, 0xbfffffee0000023f})},
- {Sign::NEG, -155, MType({0x5555355555588889, 0xfffffff000000155})},
- {Sign::NEG, -156, MType({0x5555515555558889, 0xfffffff800000055})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -155, MType({0xaaaaacaaaaaac444, 0x800000040000002a})},
- {Sign::POS, -154, MType({0xaaaabaaaaaac4444, 0x80000008000000aa})},
- {Sign::POS, -154, MType({0x5100000c2666, 0xc000001200000240})},
- {Sign::POS, -153, MType({0xaaab2aaaaac44444, 0x80000010000002aa})},
- {Sign::POS, -153, MType({0x55568dd555a37555, 0xa000001900000535})},
- {Sign::POS, -153, MType({0x2880000c26667, 0xc000002400000900})},
- {Sign::POS, -153, MType({0xaaaf5b2aac4ed778, 0xe000003100000e4a})},
- {Sign::POS, -152, MType({0xaaaeaaaaac444445, 0x8000002000000aaa})},
- {Sign::POS, -152, MType({0x6684002e21cce, 0x9000002880000f30})},
- {Sign::POS, -152, MType({0x555f19555a375558, 0xa0000032000014d5})},
- {Sign::POS, -152, MType({0xaab8f6eab287cde2, 0xb000003c80001bba})},
- {Sign::POS, -152, MType({0x1440000c26666e, 0xc000004800002400})},
- {Sign::POS, -152, MType({0x5571399567767efb, 0xd000005480002dc5})},
- {Sign::POS, -152, MType({0xaad02eaac4ed778b, 0xe00000620000392a})},
- {Sign::POS, -152, MType({0x3170402514301d, 0xf000007080004650})},
- {Sign::POS, -151, MType({0xaacaaaaac444445a, 0x8000004000002aaa})},
- {Sign::POS, -151, MType({0x557e1d7577ff70a7, 0x880000484000332d})},
- {Sign::POS, -151, MType({0x3342002e21ccf8, 0x9000005100003cc0})},
- {Sign::POS, -151, MType({0xaaea4ccae71e494d, 0x9800005a40004772})},
- {Sign::POS, -151, MType({0x55a37555a37555a7, 0xa000006400005355})},
- {Sign::POS, -151, MType({0x5ef62063b5a207, 0xa800006e40006078})},
- {Sign::POS, -151, MType({0xab1d0cab287cde6e, 0xb000007900006eea})},
- {Sign::POS, -151, MType({0x55ddf975f2787ade, 0xb800008440007ebd})},
- {Sign::POS, -151, MType({0xa20000c2666759, 0xc000009000009000})},
- {Sign::POS, -151, MType({0xab6966cb9915d3e1, 0xc800009c4000a2c2})},
- {Sign::POS, -151, MType({0x563477567767f078, 0xd00000a90000b715})},
- {Sign::POS, -151, MType({0x1037e215e50ad20, 0xd80000b64000cd08})},
- {Sign::POS, -151, MType({0xabd6caac4ed779dc, 0xe00000c40000e4aa})},
- {Sign::POS, -151, MType({0x56aeaf774a1806b0, 0xe80000d24000fe0d})},
- {Sign::POS, -151, MType({0x18b82025143039f, 0xf00000e100011940})},
- {Sign::POS, -151, MType({0xac6d9acd659ee0ad, 0xf80000f040013652})},
- {Sign::POS, -150, MType({0xabaaaaac444446ef, 0x800000800000aaaa})},
- {Sign::POS, -150, MType({0x1218811ddba1d9b, 0x840000882000bb2c})},
- {Sign::POS, -150, MType({0x569b96577ff70c5f, 0x880000908000ccb5})},
- {Sign::POS, -150, MType({0xac1907bd2bcd8b3b, 0x8c0000992000df4e})},
- {Sign::POS, -150, MType({0x19a1002e21cd235, 0x900000a20000f300})},
- {Sign::POS, -150, MType({0x571ee468a3d1394e, 0x940000ab200107d1})},
- {Sign::POS, -150, MType({0xaca7bbae71e4988b, 0x980000b480011dca})},
- {Sign::POS, -150, MType({0x234ce144d5ea7f0, 0x9c0000be200134f4})},
- {Sign::POS, -150, MType({0x57c6555a37555f82, 0xa00000c800014d55})},
- {Sign::POS, -150, MType({0xad5c8cc030ed5744, 0xa40000d2200166f6})},
- {Sign::POS, -150, MType({0x2f7b1063b5a273b, 0xa80000dc800181e0})},
- {Sign::POS, -150, MType({0x5898006c57dec76f, 0xac0000e720019e19})},
- {Sign::POS, -150, MType({0xae3dbab287cdefe3, 0xb00000f20001bbaa})},
- {Sign::POS, -150, MType({0x3e92118cc8a789f, 0xb40000fd2001da9c})},
- {Sign::POS, -150, MType({0x599a765f2787b9aa, 0xb80001088001faf5})},
- {Sign::POS, -150, MType({0xaf51fec59a49eb0a, 0xbc00011420021cbe})},
- {Sign::POS, -150, MType({0x510000c266684c6, 0xc000012000024000})},
- {Sign::POS, -150, MType({0x5ad4c172cd849ee9, 0xc400012c200264c1})},
- {Sign::POS, -150, MType({0xb0a08bb9915d5179, 0xc800013880028b0a})},
- {Sign::POS, -150, MType({0x673a92073bc1480, 0xcc0001452002b2e4})},
- {Sign::POS, -150, MType({0x5c4e6567767f2009, 0xd00001520002dc55})},
- {Sign::POS, -150, MType({0xb2310dce9b97cc1d, 0xd400015f20030766})},
- {Sign::POS, -150, MType({0x81bf115e50af0c7, 0xd800016c80033420})},
- {Sign::POS, -150, MType({0x5e0f5f7d54f14614, 0xdc00017a20036289})},
- {Sign::POS, -150, MType({0xb40baac4ed77c410, 0xe0000188000392aa})},
- {Sign::POS, -150, MType({0xa11262cb0e002c7, 0xe40001962003c48c})},
- {Sign::POS, -150, MType({0x60202674a1809a47, 0xe80001a48003f835})},
- {Sign::POS, -150, MType({0xb63901dcc1c582a0, 0xec0001b320042dae})},
- {Sign::POS, -150, MType({0xc5c1025143073df, 0xf00001c200046500})},
- {Sign::POS, -150, MType({0x6289aa8d9b594616, 0xf40001d120049e31})},
- {Sign::POS, -150, MType({0xb8c22bd659ee5155, 0xf80001e08004d94a})},
- {Sign::POS, -150, MType({0xf05f03f52b4cdae, 0xfc0001f020051654})},
- {Sign::POS, -149, MType({0xb2aaaac44444999a, 0x800001000002aaaa})},
+ {Sign::NEG, -149, 0x81fffef7'f002cb2b'4cd24d68'ff2f11ae_u128},
+ {Sign::NEG, -150, 0xfffffe00'00055555'45555588'8887ddde_u128},
+ {Sign::NEG, -150, 0xfbfffe0f'e0051653'f0fa101f'52b3971f_u128},
+ {Sign::NEG, -150, 0xf7fffe1f'8004d94a'9c9329d6'59ed3734_u128},
+ {Sign::NEG, -150, 0xf3fffe2e'e0049e31'4821006d'9b58462e_u128},
+ {Sign::NEG, -150, 0xeffffe3e'000464ff'f3a3f025'142f8c21_u128},
+ {Sign::NEG, -150, 0xebfffe4c'e0042dae'9f1c53bc'c1c4b11c_u128},
+ {Sign::NEG, -150, 0xe7fffe5b'8003f835'4a8a8474'a17fdd30_u128},
+ {Sign::NEG, -150, 0xe3fffe69'e003c48b'f5eeda0c'b0df586d_u128},
+ {Sign::NEG, -150, 0xdffffe78'000392aa'a149aac4'ed772adf_u128},
+ {Sign::NEG, -150, 0xdbfffe85'e0036289'4c9b4b5d'54f0bc96_u128},
+ {Sign::NEG, -150, 0xd7fffe93'8003341f'f7e40f15'e50a759f_u128},
+ {Sign::NEG, -150, 0xd3fffea0'e0030766'a32447ae'9b975e05_u128},
+ {Sign::NEG, -150, 0xcffffeae'0002dc55'4e5c4567'767ebdd5_u128},
+ {Sign::NEG, -150, 0xcbfffeba'e002b2e3'f98c5700'73bbbd19_u128},
+ {Sign::NEG, -150, 0xc7fffec7'80028b0a'a4b4c9b9'915d03dd_u128},
+ {Sign::NEG, -150, 0xc3fffed3'e00264c1'4fd5e952'cd845a28_u128},
+ {Sign::NEG, -150, 0xbffffee0'00023fff'faf0000c'26664806_u128},
+ {Sign::NEG, -150, 0xbbfffeeb'e0021cbe'a60356a5'9a49b57f_u128},
+ {Sign::NEG, -150, 0xb7fffef7'8001faf5'5110345f'27878a9b_u128},
+ {Sign::NEG, -150, 0xb3ffff02'e001da9b'fc16def8'cc8a4f61_u128},
+ {Sign::NEG, -150, 0xafffff0e'0001bbaa'a7179ab2'87cdcbd8_u128},
+ {Sign::NEG, -150, 0xabffff18'e0019e19'5212aa4c'57dea809_u128},
+ {Sign::NEG, -150, 0xa7ffff23'800181df'fd084f06'3b5a0bf8_u128},
+ {Sign::NEG, -150, 0xa3ffff2d'e00166f6'a7f8c8a0'30ed3fab_u128},
+ {Sign::NEG, -150, 0x9fffff38'00014d55'52e4555a'37554b29_u128},
+ {Sign::NEG, -150, 0x9bffff41'e00134f3'fdcb31f4'4d5e9676_u128},
+ {Sign::NEG, -150, 0x97ffff4b'80011dca'a8ad99ae'71e48997_u128},
+ {Sign::NEG, -150, 0x93ffff54'e00107d1'538bc648'a3d12c90_u128},
+ {Sign::NEG, -150, 0x8fffff5e'0000f2ff'fe65f002'e21cc765_u128},
+ {Sign::NEG, -150, 0x8bffff66'e000df4e'a93c4d9d'2bcd821a_u128},
+ {Sign::NEG, -150, 0x87ffff6f'8000ccb5'540f1457'7ff704b2_u128},
+ {Sign::NEG, -150, 0x83ffff77'e000bb2b'fede77f1'ddba1731_u128},
+ {Sign::NEG, -151, 0xffffff00'00015555'53555558'88888333_u128},
+ {Sign::NEG, -151, 0xf7ffff0f'c0013652'a8e7ba8d'659ed7dc_u128},
+ {Sign::NEG, -151, 0xefffff1f'0001193f'fe747e02'5142fc61_u128},
+ {Sign::NEG, -151, 0xe7ffff2d'c000fe0d'53fbfb37'4a1800c7_u128},
+ {Sign::NEG, -151, 0xdfffff3c'0000e4aa'a97e8aac'4ed77513_u128},
+ {Sign::NEG, -151, 0xd7ffff49'c000cd07'fefc81e1'5e50a947_u128},
+ {Sign::NEG, -151, 0xcfffff57'0000b715'54763356'7767ed66_u128},
+ {Sign::NEG, -151, 0xc7ffff63'c000a2c2'a9ebee8b'9915d174_u128},
+ {Sign::NEG, -151, 0xbfffff70'00008fff'ff5e0000'c2666573_u128},
+ {Sign::NEG, -151, 0xb7ffff7b'c0007ebd'54ccb135'f2787966_u128},
+ {Sign::NEG, -151, 0xafffff87'00006eea'aa3848ab'287cdd4e_u128},
+ {Sign::NEG, -151, 0xa7ffff91'c0006077'ffa109e0'63b5a12d_u128},
+ {Sign::NEG, -151, 0x9fffff9c'00005355'55073555'a3755504_u128},
+ {Sign::NEG, -151, 0x97ffffa5'c0004772'aa6b088a'e71e48d5_u128},
+ {Sign::NEG, -151, 0x8fffffaf'00003cbf'ffccbe00'2e21cca2_u128},
+ {Sign::NEG, -151, 0x87ffffb7'c000332d'552c8d35'77ff706a_u128},
+ {Sign::NEG, -152, 0xffffff80'00005555'55155555'8888885e_u128},
+ {Sign::NEG, -152, 0xefffff8f'8000464f'ffce8fc0'25142fe3_u128},
+ {Sign::NEG, -152, 0xdfffff9e'0000392a'aa8526aa'c4ed7764_u128},
+ {Sign::NEG, -152, 0xcfffffab'80002dc5'55397115'67767ee3_u128},
+ {Sign::NEG, -152, 0xbfffffb8'000023ff'ffebc000'0c26665f_u128},
+ {Sign::NEG, -152, 0xafffffc3'80001bba'aa9c5e6a'b287cdd9_u128},
+ {Sign::NEG, -152, 0x9fffffce'000014d5'554b9155'5a375553_u128},
+ {Sign::NEG, -152, 0x8fffffd7'80000f2f'fff997c0'02e21ccb_u128},
+ {Sign::NEG, -153, 0xffffffc0'00001555'554d5555'58888887_u128},
+ {Sign::NEG, -153, 0xdfffffcf'00000e4a'aaa5fa2a'ac4ed777_u128},
+ {Sign::NEG, -153, 0xbfffffdc'000008ff'fffd7800'00c26666_u128},
+ {Sign::NEG, -153, 0x9fffffe7'00000535'55541cd5'55a37555_u128},
+ {Sign::NEG, -154, 0xffffffe0'00000555'55545555'55888888_u128},
+ {Sign::NEG, -154, 0xbfffffee'0000023f'ffffaf00'000c2666_u128},
+ {Sign::NEG, -155, 0xfffffff0'00000155'55553555'55588889_u128},
+ {Sign::NEG, -156, 0xfffffff8'00000055'55555155'55558889_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -155, 0x80000004'0000002a'aaaaacaa'aaaac444_u128},
+ {Sign::POS, -154, 0x80000008'000000aa'aaaabaaa'aaac4444_u128},
+ {Sign::POS, -154, 0xc0000012'00000240'00005100'000c2666_u128},
+ {Sign::POS, -153, 0x80000010'000002aa'aaab2aaa'aac44444_u128},
+ {Sign::POS, -153, 0xa0000019'00000535'55568dd5'55a37555_u128},
+ {Sign::POS, -153, 0xc0000024'00000900'00028800'00c26667_u128},
+ {Sign::POS, -153, 0xe0000031'00000e4a'aaaf5b2a'ac4ed778_u128},
+ {Sign::POS, -152, 0x80000020'00000aaa'aaaeaaaa'ac444445_u128},
+ {Sign::POS, -152, 0x90000028'80000f30'00066840'02e21cce_u128},
+ {Sign::POS, -152, 0xa0000032'000014d5'555f1955'5a375558_u128},
+ {Sign::POS, -152, 0xb000003c'80001bba'aab8f6ea'b287cde2_u128},
+ {Sign::POS, -152, 0xc0000048'00002400'00144000'0c26666e_u128},
+ {Sign::POS, -152, 0xd0000054'80002dc5'55713995'67767efb_u128},
+ {Sign::POS, -152, 0xe0000062'0000392a'aad02eaa'c4ed778b_u128},
+ {Sign::POS, -152, 0xf0000070'80004650'00317040'2514301d_u128},
+ {Sign::POS, -151, 0x80000040'00002aaa'aacaaaaa'c444445a_u128},
+ {Sign::POS, -151, 0x88000048'4000332d'557e1d75'77ff70a7_u128},
+ {Sign::POS, -151, 0x90000051'00003cc0'00334200'2e21ccf8_u128},
+ {Sign::POS, -151, 0x9800005a'40004772'aaea4cca'e71e494d_u128},
+ {Sign::POS, -151, 0xa0000064'00005355'55a37555'a37555a7_u128},
+ {Sign::POS, -151, 0xa800006e'40006078'005ef620'63b5a207_u128},
+ {Sign::POS, -151, 0xb0000079'00006eea'ab1d0cab'287cde6e_u128},
+ {Sign::POS, -151, 0xb8000084'40007ebd'55ddf975'f2787ade_u128},
+ {Sign::POS, -151, 0xc0000090'00009000'00a20000'c2666759_u128},
+ {Sign::POS, -151, 0xc800009c'4000a2c2'ab6966cb'9915d3e1_u128},
+ {Sign::POS, -151, 0xd00000a9'0000b715'56347756'7767f078_u128},
+ {Sign::POS, -151, 0xd80000b6'4000cd08'01037e21'5e50ad20_u128},
+ {Sign::POS, -151, 0xe00000c4'0000e4aa'abd6caac'4ed779dc_u128},
+ {Sign::POS, -151, 0xe80000d2'4000fe0d'56aeaf77'4a1806b0_u128},
+ {Sign::POS, -151, 0xf00000e1'00011940'018b8202'5143039f_u128},
+ {Sign::POS, -151, 0xf80000f0'40013652'ac6d9acd'659ee0ad_u128},
+ {Sign::POS, -150, 0x80000080'0000aaaa'abaaaaac'444446ef_u128},
+ {Sign::POS, -150, 0x84000088'2000bb2c'01218811'ddba1d9b_u128},
+ {Sign::POS, -150, 0x88000090'8000ccb5'569b9657'7ff70c5f_u128},
+ {Sign::POS, -150, 0x8c000099'2000df4e'ac1907bd'2bcd8b3b_u128},
+ {Sign::POS, -150, 0x900000a2'0000f300'019a1002'e21cd235_u128},
+ {Sign::POS, -150, 0x940000ab'200107d1'571ee468'a3d1394e_u128},
+ {Sign::POS, -150, 0x980000b4'80011dca'aca7bbae'71e4988b_u128},
+ {Sign::POS, -150, 0x9c0000be'200134f4'0234ce14'4d5ea7f0_u128},
+ {Sign::POS, -150, 0xa00000c8'00014d55'57c6555a'37555f82_u128},
+ {Sign::POS, -150, 0xa40000d2'200166f6'ad5c8cc0'30ed5744_u128},
+ {Sign::POS, -150, 0xa80000dc'800181e0'02f7b106'3b5a273b_u128},
+ {Sign::POS, -150, 0xac0000e7'20019e19'5898006c'57dec76f_u128},
+ {Sign::POS, -150, 0xb00000f2'0001bbaa'ae3dbab2'87cdefe3_u128},
+ {Sign::POS, -150, 0xb40000fd'2001da9c'03e92118'cc8a789f_u128},
+ {Sign::POS, -150, 0xb8000108'8001faf5'599a765f'2787b9aa_u128},
+ {Sign::POS, -150, 0xbc000114'20021cbe'af51fec5'9a49eb0a_u128},
+ {Sign::POS, -150, 0xc0000120'00024000'0510000c'266684c6_u128},
+ {Sign::POS, -150, 0xc400012c'200264c1'5ad4c172'cd849ee9_u128},
+ {Sign::POS, -150, 0xc8000138'80028b0a'b0a08bb9'915d5179_u128},
+ {Sign::POS, -150, 0xcc000145'2002b2e4'0673a920'73bc1480_u128},
+ {Sign::POS, -150, 0xd0000152'0002dc55'5c4e6567'767f2009_u128},
+ {Sign::POS, -150, 0xd400015f'20030766'b2310dce'9b97cc1d_u128},
+ {Sign::POS, -150, 0xd800016c'80033420'081bf115'e50af0c7_u128},
+ {Sign::POS, -150, 0xdc00017a'20036289'5e0f5f7d'54f14614_u128},
+ {Sign::POS, -150, 0xe0000188'000392aa'b40baac4'ed77c410_u128},
+ {Sign::POS, -150, 0xe4000196'2003c48c'0a11262c'b0e002c7_u128},
+ {Sign::POS, -150, 0xe80001a4'8003f835'60202674'a1809a47_u128},
+ {Sign::POS, -150, 0xec0001b3'20042dae'b63901dc'c1c582a0_u128},
+ {Sign::POS, -150, 0xf00001c2'00046500'0c5c1025'143073df_u128},
+ {Sign::POS, -150, 0xf40001d1'20049e31'6289aa8d'9b594616_u128},
+ {Sign::POS, -150, 0xf80001e0'8004d94a'b8c22bd6'59ee5155_u128},
+ {Sign::POS, -150, 0xfc0001f0'20051654'0f05f03f'52b4cdae_u128},
+ {Sign::POS, -149, 0x80000100'0002aaaa'b2aaaac4'4444999a_u128},
}};
// > P = fpminimax((log(1 + x) - x)/x^2, 2, [|1, 128...|],
@@ -700,10 +703,10 @@ alignas(64) const LogRR LOG_TABLE = {
// > P;
// > dirtyinfnorm(log(1 + x)/x - x*P, [-0x1.0002143p-29 , 0x1p-29]);
// 0x1.99a3...p-121
-const Float128 BIG_COEFFS[3]{
- {Sign::NEG, -129, MType({0xb59c58e5554d581c, 0x800000000006a710})},
- {Sign::POS, -129, MType({0xde05c7c94ae9cbae, 0xaaaaaaaaaaaaaabd})},
- {Sign::NEG, -128, MType({0x0, 0x8000000000000000})},
+constexpr Float128 BIG_COEFFS[3]{
+ {Sign::NEG, -129, 0x80000000'0006a710'b59c58e5'554d581c_u128},
+ {Sign::POS, -129, 0xaaaaaaaa'aaaaaabd'de05c7c9'4ae9cbae_u128},
+ {Sign::NEG, -128, 0x80000000'00000000'00000000'00000000_u128},
};
// Reuse the output of the fast pass range reduction.
@@ -732,7 +735,7 @@ double log_accurate(int e_x, int index, double m_x) {
LLVM_LIBC_FUNCTION(double, log, (double x)) {
using FPBits_t = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
FPBits_t xbits(x);
uint64_t x_u = xbits.uintval();
diff --git a/src/math/generic/log10.cpp b/src/math/generic/log10.cpp
index b3dc8982a7fb..fb839c111e6a 100644
--- a/src/math/generic/log10.cpp
+++ b/src/math/generic/log10.cpp
@@ -14,6 +14,7 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "common_constants.h"
@@ -23,8 +24,8 @@ namespace LIBC_NAMESPACE {
// 128-bit precision dyadic floating point numbers.
using Float128 = typename fputil::DyadicFloat<128>;
-using MType = typename Float128::MantissaType;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
namespace {
@@ -37,150 +38,153 @@ constexpr double HI_ERR = 0x1.0p-85;
// Extra errors from P is from using x^2 to reduce evaluation latency.
constexpr double P_ERR = 0x1.0p-51;
-// log10(2) with 128-bit prepcision generated by SageMath with:
-// sage: (s, m, e) = RealField(128)(2).log10().sign_exponent_mantissa();
-// sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})");
-const Float128 LOG10_2(Sign::POS, /*exponent=*/-129, /*mantissa=*/
- MType({0x8f8959ac0b7c9178, 0x9a209a84fbcff798}));
-
-const LogRR LOG10_TABLE = {
+// log10(2) with 128-bit precision generated by SageMath with:
+// def format_hex(value):
+// l = hex(value)[2:]
+// n = 8
+// x = [l[i:i + n] for i in range(0, len(l), n)]
+// return "0x" + "'".join(x) + "_u128"
+// (s, m, e) = RealField(128)(2).log10().sign_exponent_mantissa();
+// print(format_hex(m));
+constexpr Float128 LOG10_2(Sign::POS, /*exponent=*/-129, /*mantissa=*/
+ 0x9a209a84'fbcff798'8f8959ac'0b7c9178_u128);
+
+alignas(64) constexpr LogRR LOG10_TABLE = {
// -log10(r) with 128-bit precision generated by SageMath with:
//
// for i in range(128):
// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) );
// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent();
- // print("{Sign::POS,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64)
- // % 2^64),
- // "})},");
+ // print("{Sign::POS,", e, ", format_hex(m), "},");
/* .step_1 = */ {
- {Sign::POS, 0, MType(0)},
- {Sign::POS, -136, MType({0x65af394fe05eafd3, 0xdf3b5ebbda7e186b})},
- {Sign::POS, -135, MType({0xa8fb8d87b30163b5, 0xe01d40572f029c16})},
- {Sign::POS, -134, MType({0x6bb0170e5bb5d630, 0xa8c1263ac3f57eb3})},
- {Sign::POS, -134, MType({0xfc2ea6eb0ea1370e, 0xe1e841bbc26204e5})},
- {Sign::POS, -133, MType({0xdc8a199a4bb63382, 0x8dc2eb02274d6ff4})},
- {Sign::POS, -133, MType({0x86b57ea610c7db33, 0xaacde920361dd054})},
- {Sign::POS, -133, MType({0x5f034a40e6a2f09d, 0xc81618eb15421bab})},
- {Sign::POS, -133, MType({0x594a31b2c5cc891c, 0xe59c7e66c5fedb4b})},
- {Sign::POS, -133, MType({0x221efda58221904b, 0xf477584f97b654de})},
- {Sign::POS, -132, MType({0x68a0dc47567691c9, 0x892e821975106e09})},
- {Sign::POS, -132, MType({0x10bc94f44d216b49, 0x9841c66e17dfe7da})},
- {Sign::POS, -132, MType({0xe303ea7e23c9d6fb, 0x9fd7be3318306cc5})},
- {Sign::POS, -132, MType({0xce697dbaa00d4c7d, 0xaf1cb35bf494a8dd})},
- {Sign::POS, -132, MType({0x9c216079dcf0ea96, 0xbe8380a2fa7eba5a})},
- {Sign::POS, -132, MType({0x75278940eecfc3a9, 0xc643c7758283a271})},
- {Sign::POS, -132, MType({0x2d3467d253e2d1fc, 0xd5de75ec27e4fe68})},
- {Sign::POS, -132, MType({0xead4055dcdec7b22, 0xddb904e8f1272a95})},
- {Sign::POS, -132, MType({0xe1e0dda0b3d375a4, 0xed88f6bb355fa196})},
- {Sign::POS, -132, MType({0x38dc40c4fe11e608, 0xf57e8281ade9d92d})},
- {Sign::POS, -131, MType({0x3bcdcfe7b23976cd, 0x82c2941bb20bbe1f})},
- {Sign::POS, -131, MType({0x456350b0bda452a6, 0x86cb36632807cdcd})},
- {Sign::POS, -131, MType({0x78185dcc37fda01a, 0x8eeaa306458b760a})},
- {Sign::POS, -131, MType({0x307643adbbbde1b3, 0x9301839512fc1168})},
- {Sign::POS, -131, MType({0x6c449d409f883fe3, 0x9b3dd1d550c41443})},
- {Sign::POS, -131, MType({0x8ea7b30c8b4ad886, 0x9f6356aa03c34389})},
- {Sign::POS, -131, MType({0x961c6e690d8879b4, 0xa7bd56cdde5d76a2})},
- {Sign::POS, -131, MType({0x42643ced81ec14a, 0xabf1ea3e1d7bd7cf})},
- {Sign::POS, -131, MType({0x4742fb3d0b5cdd19, 0xb02b9af74c2f879e})},
- {Sign::POS, -131, MType({0xf7e2ab36f09e9014, 0xb8ae8671b3d7dd6c})},
- {Sign::POS, -131, MType({0x8d3fc63485e7ff13, 0xbcf7dabd87c01afc})},
- {Sign::POS, -131, MType({0xf3edc49375fbc5a5, 0xc1467f694d10a581})},
- {Sign::POS, -131, MType({0x5fcd7d0ce937375f, 0xc9f3ef07e1f3fc5e})},
- {Sign::POS, -131, MType({0x58252dada9f06111, 0xce52d50b94fa253a})},
- {Sign::POS, -131, MType({0x62f01e5ff43708ab, 0xd2b74192fae43777})},
- {Sign::POS, -131, MType({0x481d9b3131f52639, 0xd72142a84ca85abd})},
- {Sign::POS, -131, MType({0xb305ced1419fe924, 0xdb90e68b8abf14af})},
- {Sign::POS, -131, MType({0x849266a85513dc6d, 0xe48150cf32888b9c})},
- {Sign::POS, -131, MType({0x80ecf3266b4dcf4, 0xe90234c65a15e533})},
- {Sign::POS, -131, MType({0xe1e0dda0b3d375a4, 0xed88f6bb355fa196})},
- {Sign::POS, -131, MType({0xce3537a3a211b25b, 0xf215a60b6557943f})},
- {Sign::POS, -131, MType({0x5dab68307fedefcd, 0xf6a852513757dfbd})},
- {Sign::POS, -131, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})},
- {Sign::POS, -130, MType({0x18aa302171017dcb, 0x8242724a155219f3})},
- {Sign::POS, -130, MType({0xabc7e698502d43c0, 0x849812d0ccbb5cbd})},
- {Sign::POS, -130, MType({0xc339089a51663370, 0x86f0dab1ab5822b6})},
- {Sign::POS, -130, MType({0x26f70b34ce5cf201, 0x894cd27d9f182c63})},
- {Sign::POS, -130, MType({0x676f20a87ab433df, 0x8bac02e8ac3e09ac})},
- {Sign::POS, -130, MType({0x6db4169cc4b83bc3, 0x8e0e74caae062e24})},
- {Sign::POS, -130, MType({0xcd3fdb2fad0d1fd6, 0x907431201c7f651a})},
- {Sign::POS, -130, MType({0x49d03e163250d1d4, 0x92dd410ad7bfe103})},
- {Sign::POS, -130, MType({0x9ec7dc02d5e723b9, 0x9549add2f8a3c7e0})},
- {Sign::POS, -130, MType({0x34698d03a5442573, 0x97b980e7a743d71c})},
- {Sign::POS, -130, MType({0x522904d1e47f3de, 0x9a2cc3dff7548556})},
- {Sign::POS, -130, MType({0x791a72646c87b976, 0x9ca3807bca9fe93f})},
- {Sign::POS, -130, MType({0x3826f190d655d736, 0x9f1dc0a4b9cea286})},
- {Sign::POS, -130, MType({0x544ab3e48199b299, 0xa19b8e6f03b60e45})},
- {Sign::POS, -130, MType({0xbe775fa82961114e, 0xa41cf41a83643487})},
- {Sign::POS, -130, MType({0x45798e5019e6c082, 0xa6a1fc13ad241953})},
- {Sign::POS, -130, MType({0x91fb1ed0cdc4d1fb, 0xa92ab0f492b772bd})},
- {Sign::POS, -130, MType({0x818b8b9cbbd17b72, 0xabb71d85ef05380d})},
- {Sign::POS, -130, MType({0xa50c2fea60c5b3b2, 0xae474cc0397f0d4f})},
- {Sign::POS, -130, MType({0x58ea34980ad8b720, 0xb0db49ccc1823c8e})},
- {Sign::POS, -130, MType({0x4b5f71941be508a4, 0xb3732006d1fbbba5})},
- {Sign::POS, -130, MType({0x9e405fb8bcb1ff1e, 0xb60edafcdd99ad1d})},
- {Sign::POS, -130, MType({0x9e405fb8bcb1ff1e, 0xb60edafcdd99ad1d})},
- {Sign::POS, -130, MType({0xf7e2ab36f09e9014, 0xb8ae8671b3d7dd6c})},
- {Sign::POS, -130, MType({0xc669639640c305bb, 0xbb522e5dbf37f63b})},
- {Sign::POS, -130, MType({0xa3dc9e464e98764b, 0xbdf9def04cf980ff})},
- {Sign::POS, -130, MType({0xffd3256b59fa9c59, 0xc0a5a490dea95b5e})},
- {Sign::POS, -130, MType({0xb0a2d48672a051a5, 0xc3558be085e3f4bc})},
- {Sign::POS, -130, MType({0xb0a2d48672a051a5, 0xc3558be085e3f4bc})},
- {Sign::POS, -130, MType({0xacb2ca5d4ca1c10e, 0xc609a1bb4aa98f59})},
- {Sign::POS, -130, MType({0x43690b9e3cde0d02, 0xc8c1f3399ca7d33b})},
- {Sign::POS, -130, MType({0x18b1fd60383f7e5a, 0xcb7e8db1cfe04827})},
- {Sign::POS, -130, MType({0x248757e5f45af3d, 0xce3f7eb9a517c969})},
- {Sign::POS, -130, MType({0x7c4acd605be48bc1, 0xd104d427de7fbcc4})},
- {Sign::POS, -130, MType({0x7c4acd605be48bc1, 0xd104d427de7fbcc4})},
- {Sign::POS, -130, MType({0x58ff63629a92652d, 0xd3ce9c15e10ec927})},
- {Sign::POS, -130, MType({0x6b49be3bd8c89f10, 0xd69ce4e16303fcdd})},
- {Sign::POS, -130, MType({0xe6dd603a881e9060, 0xd96fbd2e2814c9cc})},
- {Sign::POS, -130, MType({0xe6dd603a881e9060, 0xd96fbd2e2814c9cc})},
- {Sign::POS, -130, MType({0x89e281c98c1d705c, 0xdc4733e7cbcbfc8c})},
- {Sign::POS, -130, MType({0xdc0db7cf0cce9f32, 0xdf2358439aa5dd12})},
- {Sign::POS, -130, MType({0xfdf1c5b846db9deb, 0xe20439c27a7c01b8})},
- {Sign::POS, -130, MType({0xfdf1c5b846db9deb, 0xe20439c27a7c01b8})},
- {Sign::POS, -130, MType({0x3dd7eab48869c402, 0xe4e9e832e2da0c05})},
- {Sign::POS, -130, MType({0x4e8fcc900b41daef, 0xe7d473b2e5db8f2a})},
- {Sign::POS, -130, MType({0x4e8fcc900b41daef, 0xe7d473b2e5db8f2a})},
- {Sign::POS, -130, MType({0x7593e1a9e917359a, 0xeac3ecb24a3ac7b4})},
- {Sign::POS, -130, MType({0xe7741396b49e1ce5, 0xedb863f4b73f982d})},
- {Sign::POS, -130, MType({0xe7741396b49e1ce5, 0xedb863f4b73f982d})},
- {Sign::POS, -130, MType({0xc8ba4f8f47b85a5c, 0xf0b1ea93f34675a7})},
- {Sign::POS, -130, MType({0x7007c1276821b705, 0xf3b09202359f9787})},
- {Sign::POS, -130, MType({0x7007c1276821b705, 0xf3b09202359f9787})},
- {Sign::POS, -130, MType({0x7ee19afe6db7e324, 0xf6b46c0c8c8fdea1})},
- {Sign::POS, -130, MType({0xedf54f37f6d40420, 0xf9bd8add584687f0})},
- {Sign::POS, -130, MType({0xedf54f37f6d40420, 0xf9bd8add584687f0})},
- {Sign::POS, -130, MType({0xefe52ccf03e7dee1, 0xfccc00fedba4e6fb})},
- {Sign::POS, -130, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})},
- {Sign::POS, -130, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})},
- {Sign::POS, -129, MType({0xe0b571f5c91b0446, 0x817c9fa643880404})},
- {Sign::POS, -129, MType({0x7178594bef2def59, 0x830c17427ea55eca})},
- {Sign::POS, -129, MType({0x7178594bef2def59, 0x830c17427ea55eca})},
- {Sign::POS, -129, MType({0x9a741bb171158d2a, 0x849e6196487c1d1c})},
- {Sign::POS, -129, MType({0x9a741bb171158d2a, 0x849e6196487c1d1c})},
- {Sign::POS, -129, MType({0x1a618264446cb495, 0x863388eb55ebd295})},
- {Sign::POS, -129, MType({0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})},
- {Sign::POS, -129, MType({0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})},
- {Sign::POS, -129, MType({0xabe0b522230f7d14, 0x896698dce4cff76c})},
- {Sign::POS, -129, MType({0xabe0b522230f7d14, 0x896698dce4cff76c})},
- {Sign::POS, -129, MType({0xd28e8adafea703b4, 0x8b04972e9d4d3011})},
- {Sign::POS, -129, MType({0x208422d83be34b27, 0x8ca59def7b5cefc5})},
- {Sign::POS, -129, MType({0x208422d83be34b27, 0x8ca59def7b5cefc5})},
- {Sign::POS, -129, MType({0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})},
- {Sign::POS, -129, MType({0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})},
- {Sign::POS, -129, MType({0xda982a614e12c6dd, 0x8ff0f2d7960a075c})},
- {Sign::POS, -129, MType({0xda982a614e12c6dd, 0x8ff0f2d7960a075c})},
- {Sign::POS, -129, MType({0x38401fc1c1b5c2c, 0x919b58b0d999bbc8})},
- {Sign::POS, -129, MType({0x38401fc1c1b5c2c, 0x919b58b0d999bbc8})},
- {Sign::POS, -129, MType({0xa9b55d3f16da746a, 0x9348f6614f821394})},
- {Sign::POS, -129, MType({0xa9b55d3f16da746a, 0x9348f6614f821394})},
- {Sign::POS, -129, MType({0x88d2d1473d4f7f5, 0x94f9d870aac256a5})},
- {Sign::POS, -129, MType({0x88d2d1473d4f7f5, 0x94f9d870aac256a5})},
- {Sign::POS, -129, MType({0x7c1e117dea19e9e6, 0x96ae0bb05c35d5bd})},
- {Sign::POS, -129, MType({0x7c1e117dea19e9e6, 0x96ae0bb05c35d5bd})},
- {Sign::POS, -129, MType({0x336db0630f536fb9, 0x98659d3dd9b12532})},
- {Sign::POS, 0, MType(0)},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -136, 0xdf3b5ebb'da7e186b'65af394f'e05eafd3_u128},
+ {Sign::POS, -135, 0xe01d4057'2f029c16'a8fb8d87'b30163b5_u128},
+ {Sign::POS, -134, 0xa8c1263a'c3f57eb3'6bb0170e'5bb5d630_u128},
+ {Sign::POS, -134, 0xe1e841bb'c26204e5'fc2ea6eb'0ea1370e_u128},
+ {Sign::POS, -133, 0x8dc2eb02'274d6ff4'dc8a199a'4bb63382_u128},
+ {Sign::POS, -133, 0xaacde920'361dd054'86b57ea6'10c7db33_u128},
+ {Sign::POS, -133, 0xc81618eb'15421bab'5f034a40'e6a2f09d_u128},
+ {Sign::POS, -133, 0xe59c7e66'c5fedb4b'594a31b2'c5cc891c_u128},
+ {Sign::POS, -133, 0xf477584f'97b654de'221efda5'8221904b_u128},
+ {Sign::POS, -132, 0x892e8219'75106e09'68a0dc47'567691c9_u128},
+ {Sign::POS, -132, 0x9841c66e'17dfe7da'10bc94f4'4d216b49_u128},
+ {Sign::POS, -132, 0x9fd7be33'18306cc5'e303ea7e'23c9d6fb_u128},
+ {Sign::POS, -132, 0xaf1cb35b'f494a8dd'ce697dba'a00d4c7d_u128},
+ {Sign::POS, -132, 0xbe8380a2'fa7eba5a'9c216079'dcf0ea96_u128},
+ {Sign::POS, -132, 0xc643c775'8283a271'75278940'eecfc3a9_u128},
+ {Sign::POS, -132, 0xd5de75ec'27e4fe68'2d3467d2'53e2d1fc_u128},
+ {Sign::POS, -132, 0xddb904e8'f1272a95'ead4055d'cdec7b22_u128},
+ {Sign::POS, -132, 0xed88f6bb'355fa196'e1e0dda0'b3d375a4_u128},
+ {Sign::POS, -132, 0xf57e8281'ade9d92d'38dc40c4'fe11e608_u128},
+ {Sign::POS, -131, 0x82c2941b'b20bbe1f'3bcdcfe7'b23976cd_u128},
+ {Sign::POS, -131, 0x86cb3663'2807cdcd'456350b0'bda452a6_u128},
+ {Sign::POS, -131, 0x8eeaa306'458b760a'78185dcc'37fda01a_u128},
+ {Sign::POS, -131, 0x93018395'12fc1168'307643ad'bbbde1b3_u128},
+ {Sign::POS, -131, 0x9b3dd1d5'50c41443'6c449d40'9f883fe3_u128},
+ {Sign::POS, -131, 0x9f6356aa'03c34389'8ea7b30c'8b4ad886_u128},
+ {Sign::POS, -131, 0xa7bd56cd'de5d76a2'961c6e69'0d8879b4_u128},
+ {Sign::POS, -131, 0xabf1ea3e'1d7bd7cf'042643ce'd81ec14a_u128},
+ {Sign::POS, -131, 0xb02b9af7'4c2f879e'4742fb3d'0b5cdd19_u128},
+ {Sign::POS, -131, 0xb8ae8671'b3d7dd6c'f7e2ab36'f09e9014_u128},
+ {Sign::POS, -131, 0xbcf7dabd'87c01afc'8d3fc634'85e7ff13_u128},
+ {Sign::POS, -131, 0xc1467f69'4d10a581'f3edc493'75fbc5a5_u128},
+ {Sign::POS, -131, 0xc9f3ef07'e1f3fc5e'5fcd7d0c'e937375f_u128},
+ {Sign::POS, -131, 0xce52d50b'94fa253a'58252dad'a9f06111_u128},
+ {Sign::POS, -131, 0xd2b74192'fae43777'62f01e5f'f43708ab_u128},
+ {Sign::POS, -131, 0xd72142a8'4ca85abd'481d9b31'31f52639_u128},
+ {Sign::POS, -131, 0xdb90e68b'8abf14af'b305ced1'419fe924_u128},
+ {Sign::POS, -131, 0xe48150cf'32888b9c'849266a8'5513dc6d_u128},
+ {Sign::POS, -131, 0xe90234c6'5a15e533'080ecf32'66b4dcf4_u128},
+ {Sign::POS, -131, 0xed88f6bb'355fa196'e1e0dda0'b3d375a4_u128},
+ {Sign::POS, -131, 0xf215a60b'6557943f'ce3537a3'a211b25b_u128},
+ {Sign::POS, -131, 0xf6a85251'3757dfbd'5dab6830'7fedefcd_u128},
+ {Sign::POS, -131, 0xffdfe15d'e3c01bac'1be2585c'279c50a5_u128},
+ {Sign::POS, -130, 0x8242724a'155219f3'18aa3021'71017dcb_u128},
+ {Sign::POS, -130, 0x849812d0'ccbb5cbd'abc7e698'502d43c0_u128},
+ {Sign::POS, -130, 0x86f0dab1'ab5822b6'c339089a'51663370_u128},
+ {Sign::POS, -130, 0x894cd27d'9f182c63'26f70b34'ce5cf201_u128},
+ {Sign::POS, -130, 0x8bac02e8'ac3e09ac'676f20a8'7ab433df_u128},
+ {Sign::POS, -130, 0x8e0e74ca'ae062e24'6db4169c'c4b83bc3_u128},
+ {Sign::POS, -130, 0x90743120'1c7f651a'cd3fdb2f'ad0d1fd6_u128},
+ {Sign::POS, -130, 0x92dd410a'd7bfe103'49d03e16'3250d1d4_u128},
+ {Sign::POS, -130, 0x9549add2'f8a3c7e0'9ec7dc02'd5e723b9_u128},
+ {Sign::POS, -130, 0x97b980e7'a743d71c'34698d03'a5442573_u128},
+ {Sign::POS, -130, 0x9a2cc3df'f7548556'0522904d'1e47f3de_u128},
+ {Sign::POS, -130, 0x9ca3807b'ca9fe93f'791a7264'6c87b976_u128},
+ {Sign::POS, -130, 0x9f1dc0a4'b9cea286'3826f190'd655d736_u128},
+ {Sign::POS, -130, 0xa19b8e6f'03b60e45'544ab3e4'8199b299_u128},
+ {Sign::POS, -130, 0xa41cf41a'83643487'be775fa8'2961114e_u128},
+ {Sign::POS, -130, 0xa6a1fc13'ad241953'45798e50'19e6c082_u128},
+ {Sign::POS, -130, 0xa92ab0f4'92b772bd'91fb1ed0'cdc4d1fb_u128},
+ {Sign::POS, -130, 0xabb71d85'ef05380d'818b8b9c'bbd17b72_u128},
+ {Sign::POS, -130, 0xae474cc0'397f0d4f'a50c2fea'60c5b3b2_u128},
+ {Sign::POS, -130, 0xb0db49cc'c1823c8e'58ea3498'0ad8b720_u128},
+ {Sign::POS, -130, 0xb3732006'd1fbbba5'4b5f7194'1be508a4_u128},
+ {Sign::POS, -130, 0xb60edafc'dd99ad1d'9e405fb8'bcb1ff1e_u128},
+ {Sign::POS, -130, 0xb60edafc'dd99ad1d'9e405fb8'bcb1ff1e_u128},
+ {Sign::POS, -130, 0xb8ae8671'b3d7dd6c'f7e2ab36'f09e9014_u128},
+ {Sign::POS, -130, 0xbb522e5d'bf37f63b'c6696396'40c305bb_u128},
+ {Sign::POS, -130, 0xbdf9def0'4cf980ff'a3dc9e46'4e98764b_u128},
+ {Sign::POS, -130, 0xc0a5a490'dea95b5e'ffd3256b'59fa9c59_u128},
+ {Sign::POS, -130, 0xc3558be0'85e3f4bc'b0a2d486'72a051a5_u128},
+ {Sign::POS, -130, 0xc3558be0'85e3f4bc'b0a2d486'72a051a5_u128},
+ {Sign::POS, -130, 0xc609a1bb'4aa98f59'acb2ca5d'4ca1c10e_u128},
+ {Sign::POS, -130, 0xc8c1f339'9ca7d33b'43690b9e'3cde0d02_u128},
+ {Sign::POS, -130, 0xcb7e8db1'cfe04827'18b1fd60'383f7e5a_u128},
+ {Sign::POS, -130, 0xce3f7eb9'a517c969'0248757e'5f45af3d_u128},
+ {Sign::POS, -130, 0xd104d427'de7fbcc4'7c4acd60'5be48bc1_u128},
+ {Sign::POS, -130, 0xd104d427'de7fbcc4'7c4acd60'5be48bc1_u128},
+ {Sign::POS, -130, 0xd3ce9c15'e10ec927'58ff6362'9a92652d_u128},
+ {Sign::POS, -130, 0xd69ce4e1'6303fcdd'6b49be3b'd8c89f10_u128},
+ {Sign::POS, -130, 0xd96fbd2e'2814c9cc'e6dd603a'881e9060_u128},
+ {Sign::POS, -130, 0xd96fbd2e'2814c9cc'e6dd603a'881e9060_u128},
+ {Sign::POS, -130, 0xdc4733e7'cbcbfc8c'89e281c9'8c1d705c_u128},
+ {Sign::POS, -130, 0xdf235843'9aa5dd12'dc0db7cf'0cce9f32_u128},
+ {Sign::POS, -130, 0xe20439c2'7a7c01b8'fdf1c5b8'46db9deb_u128},
+ {Sign::POS, -130, 0xe20439c2'7a7c01b8'fdf1c5b8'46db9deb_u128},
+ {Sign::POS, -130, 0xe4e9e832'e2da0c05'3dd7eab4'8869c402_u128},
+ {Sign::POS, -130, 0xe7d473b2'e5db8f2a'4e8fcc90'0b41daef_u128},
+ {Sign::POS, -130, 0xe7d473b2'e5db8f2a'4e8fcc90'0b41daef_u128},
+ {Sign::POS, -130, 0xeac3ecb2'4a3ac7b4'7593e1a9'e917359a_u128},
+ {Sign::POS, -130, 0xedb863f4'b73f982d'e7741396'b49e1ce5_u128},
+ {Sign::POS, -130, 0xedb863f4'b73f982d'e7741396'b49e1ce5_u128},
+ {Sign::POS, -130, 0xf0b1ea93'f34675a7'c8ba4f8f'47b85a5c_u128},
+ {Sign::POS, -130, 0xf3b09202'359f9787'7007c127'6821b705_u128},
+ {Sign::POS, -130, 0xf3b09202'359f9787'7007c127'6821b705_u128},
+ {Sign::POS, -130, 0xf6b46c0c'8c8fdea1'7ee19afe'6db7e324_u128},
+ {Sign::POS, -130, 0xf9bd8add'584687f0'edf54f37'f6d40420_u128},
+ {Sign::POS, -130, 0xf9bd8add'584687f0'edf54f37'f6d40420_u128},
+ {Sign::POS, -130, 0xfccc00fe'dba4e6fb'efe52ccf'03e7dee1_u128},
+ {Sign::POS, -130, 0xffdfe15d'e3c01bac'1be2585c'279c50a5_u128},
+ {Sign::POS, -130, 0xffdfe15d'e3c01bac'1be2585c'279c50a5_u128},
+ {Sign::POS, -129, 0x817c9fa6'43880404'e0b571f5'c91b0446_u128},
+ {Sign::POS, -129, 0x830c1742'7ea55eca'7178594b'ef2def59_u128},
+ {Sign::POS, -129, 0x830c1742'7ea55eca'7178594b'ef2def59_u128},
+ {Sign::POS, -129, 0x849e6196'487c1d1c'9a741bb1'71158d2a_u128},
+ {Sign::POS, -129, 0x849e6196'487c1d1c'9a741bb1'71158d2a_u128},
+ {Sign::POS, -129, 0x863388eb'55ebd295'1a618264'446cb495_u128},
+ {Sign::POS, -129, 0x87cb97c3'ff9eac18'71dbdbbe'c51d7657_u128},
+ {Sign::POS, -129, 0x87cb97c3'ff9eac18'71dbdbbe'c51d7657_u128},
+ {Sign::POS, -129, 0x896698dc'e4cff76c'abe0b522'230f7d14_u128},
+ {Sign::POS, -129, 0x896698dc'e4cff76c'abe0b522'230f7d14_u128},
+ {Sign::POS, -129, 0x8b04972e'9d4d3011'd28e8ada'fea703b4_u128},
+ {Sign::POS, -129, 0x8ca59def'7b5cefc5'208422d8'3be34b27_u128},
+ {Sign::POS, -129, 0x8ca59def'7b5cefc5'208422d8'3be34b27_u128},
+ {Sign::POS, -129, 0x8e49b895'5e3ffb8a'c385cf49'402af0e4_u128},
+ {Sign::POS, -129, 0x8e49b895'5e3ffb8a'c385cf49'402af0e4_u128},
+ {Sign::POS, -129, 0x8ff0f2d7'960a075c'da982a61'4e12c6dd_u128},
+ {Sign::POS, -129, 0x8ff0f2d7'960a075c'da982a61'4e12c6dd_u128},
+ {Sign::POS, -129, 0x919b58b0'd999bbc8'038401fc'1c1b5c2c_u128},
+ {Sign::POS, -129, 0x919b58b0'd999bbc8'038401fc'1c1b5c2c_u128},
+ {Sign::POS, -129, 0x9348f661'4f821394'a9b55d3f'16da746a_u128},
+ {Sign::POS, -129, 0x9348f661'4f821394'a9b55d3f'16da746a_u128},
+ {Sign::POS, -129, 0x94f9d870'aac256a5'088d2d14'73d4f7f5_u128},
+ {Sign::POS, -129, 0x94f9d870'aac256a5'088d2d14'73d4f7f5_u128},
+ {Sign::POS, -129, 0x96ae0bb0'5c35d5bd'7c1e117d'ea19e9e6_u128},
+ {Sign::POS, -129, 0x96ae0bb0'5c35d5bd'7c1e117d'ea19e9e6_u128},
+ {Sign::POS, -129, 0x98659d3d'd9b12532'336db063'0f536fb9_u128},
+ {Sign::POS, 0, 0_u128},
},
// -log10(r) for the second step, generated by SageMath with:
//
@@ -188,524 +192,524 @@ const LogRR LOG10_TABLE = {
// r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) );
// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent();
// print("{Sign::POS," if s == -1 else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_2 = */
{
- {Sign::NEG, -137, MType({0x7f1ce002fa34131b, 0xdeca729013cd7c31})},
- {Sign::NEG, -137, MType({0x639afa085dd8b4c7, 0xdb5475b44946d986})},
- {Sign::NEG, -137, MType({0x5512632fe9a58cb, 0xd7de6b0e10cab7d2})},
- {Sign::NEG, -137, MType({0xb5380a9953117d07, 0xd468529cfc6fb395})},
- {Sign::NEG, -137, MType({0x70af2d7d53be1f31, 0xd0f22c609e474741})},
- {Sign::NEG, -137, MType({0xccd499c49b74cc2, 0xcd7bf858885dcae2})},
- {Sign::NEG, -137, MType({0x5b51ddc3987ebfb8, 0xca05b6844cba73cf})},
- {Sign::NEG, -137, MType({0x49375f5189b3782b, 0xc68f66e37d5f545a})},
- {Sign::NEG, -137, MType({0xf6e57738865c712f, 0xc3190975ac495b7a})},
- {Sign::NEG, -137, MType({0xca02b10a8c712acd, 0xbfa29e3a6b70547e})},
- {Sign::NEG, -137, MType({0x78e5038210208151, 0xbc2c25314cc6e6b6})},
- {Sign::NEG, -137, MType({0xfa099ecd71ee0ea, 0xb8b59e59e23a9524})},
- {Sign::NEG, -137, MType({0xeeb445ccb8fb09ed, 0xb53f09b3bdb3be28})},
- {Sign::NEG, -137, MType({0xc352fff18a1c02fb, 0xb1c8673e71159b33})},
- {Sign::NEG, -137, MType({0x7949e03ecf9b390b, 0xae51b6f98e3e406e})},
- {Sign::NEG, -137, MType({0x2681f33f30aadedc, 0xaadaf8e4a7069c6c})},
- {Sign::NEG, -137, MType({0xf01d5496eea213b3, 0xa7642cff4d4277d6})},
- {Sign::NEG, -137, MType({0xe92ef555ff1de975, 0xa3ed534912c0751d})},
- {Sign::NEG, -137, MType({0xeb0c7519b3e7c1e0, 0xa0766bc1894a1022})},
- {Sign::NEG, -137, MType({0xf60d204ff0fe5296, 0x9c21b6e91e7f03a3})},
- {Sign::NEG, -137, MType({0x125c19a4f057c18b, 0x98aab0491050bea8})},
- {Sign::NEG, -137, MType({0x7e9383ce1bdf9575, 0x95339bd64cd953e7})},
- {Sign::NEG, -137, MType({0xbf274f4d8f770253, 0x91bc799065cc57d6})},
- {Sign::NEG, -137, MType({0x656bd9b758fe44ba, 0x8e454976ecd836ad})},
- {Sign::NEG, -137, MType({0xbfdd2c7f388fc014, 0x8ace0b8973a63413})},
- {Sign::NEG, -137, MType({0x83fbf6ed936c493a, 0x8756bfc78bda6ad0})},
- {Sign::NEG, -137, MType({0x71bfa9a18bec01cc, 0x83df6630c713cc76})},
- {Sign::NEG, -137, MType({0xf09d19f56dbfef72, 0x8067fec4b6ec2111})},
- {Sign::NEG, -138, MType({0x4c422713b1642228, 0xf9e11305d9f00dad})},
- {Sign::NEG, -138, MType({0xc3c7c5699b7a0a4, 0xf2f20cd5f58de39a})},
- {Sign::NEG, -138, MType({0xb8db7c69e3fa0797, 0xec02eaf8e3c656ff})},
- {Sign::NEG, -138, MType({0xa083eb05506ff7ed, 0xe513ad6dc7a3a553})},
- {Sign::NEG, -138, MType({0xc21595e745f1fa15, 0xde245433c425b5c5})},
- {Sign::NEG, -138, MType({0xb9d5bcdbfe719389, 0xd734df49fc42189b})},
- {Sign::NEG, -138, MType({0xa17a1e85e93461f4, 0xd0454eaf92e4068b})},
- {Sign::NEG, -138, MType({0xe3537584da333fda, 0xc955a263aaec6016})},
- {Sign::NEG, -138, MType({0x963177f24682c2, 0xc265da656731ace5})},
- {Sign::NEG, -138, MType({0x4ac037347bcfc50e, 0xbb75f6b3ea801b1e})},
- {Sign::NEG, -138, MType({0x901a736a4364cdfd, 0xb485f74e57997ec6})},
- {Sign::NEG, -138, MType({0xbb550acc3b9d7247, 0xad95dc33d1355117})},
- {Sign::NEG, -138, MType({0x663cf2b27e8f1ffb, 0xa6a5a5637a00afdc})},
- {Sign::NEG, -138, MType({0x5f89bd08feb39952, 0x9fb552dc749e5cca})},
- {Sign::NEG, -138, MType({0x23c2623c73f494db, 0x98c4e49de3a6bcdd})},
- {Sign::NEG, -138, MType({0x4937d3b5485af61e, 0x91d45aa6e9a7d7b0})},
- {Sign::NEG, -138, MType({0xdf14214e7a6d8111, 0x8ae3b4f6a92556d9})},
- {Sign::NEG, -138, MType({0xbf7cfc14999fb4bc, 0x83f2f38c44988544})},
- {Sign::NEG, -139, MType({0xa990c0ee569a8d51, 0xfa042ccdbce09d15})},
- {Sign::NEG, -139, MType({0xa38463e9d941e1c2, 0xec223b0b32227c9e})},
- {Sign::NEG, -139, MType({0xba0324530edaa03f, 0xde4011cf2daaff31})},
- {Sign::NEG, -139, MType({0x5e997a02dad7ace7, 0xd05db117f419b857})},
- {Sign::NEG, -139, MType({0x4a14676d4d0f817e, 0xc27b18e3c9f977c7})},
- {Sign::NEG, -139, MType({0x857c002ee7a1e473, 0xb4984930f3c0481c})},
- {Sign::NEG, -139, MType({0x5923b2eb72d8012a, 0xa6b541fdb5cf6d89})},
- {Sign::NEG, -139, MType({0x21cde8f85ca1f9fd, 0x98d203485473648b})},
- {Sign::NEG, -139, MType({0xbe08e08b1d212d4, 0x8aee8d0f13e3e09e})},
- {Sign::NEG, -140, MType({0x695023998e6bd7b0, 0xfa15bea0708795e1})},
- {Sign::NEG, -140, MType({0x634cea6750617a92, 0xde4df4140b42822f})},
- {Sign::NEG, -140, MType({0xfbd7e970aef9dbb8, 0xc285ba757feb2781})},
- {Sign::NEG, -140, MType({0x9aedc1c1ba7d0695, 0xa6bd11c1564a8ace})},
- {Sign::NEG, -140, MType({0x8d306ba207233c44, 0x8af3f9f41600120a})},
- {Sign::NEG, -141, MType({0x856a0a3a00fcf3c1, 0xde54e6148d030322})},
- {Sign::NEG, -141, MType({0xb3a2c1407cf6d38d, 0xa6c0fa00de35f314})},
- {Sign::NEG, -142, MType({0xd791cf6a70c3a504, 0xde585f4c5bbbcd3d})},
- {Sign::NEG, -143, MType({0x10a633f2c4a8ea22, 0xde5a1bf627b1f68f})},
- {Sign::NEG, 0, MType({0x0, 0x0})},
- {Sign::POS, -143, MType({0xed4a68e5e6e83ddf, 0xde5d95658a729eab})},
- {Sign::POS, -142, MType({0x3281f1872cdbee94, 0xde5f522b21e3e25a})},
- {Sign::POS, -141, MType({0xf1466edaa96e356e, 0xa6c8cb3b7e5bbbfd})},
- {Sign::POS, -141, MType({0x8a607fd695dfc3d9, 0xde62cbd21e895473})},
- {Sign::POS, -140, MType({0xc36b8713ceefe2de, 0x8afed57032bebc7c})},
- {Sign::POS, -140, MType({0x5c2e76c953e3e3e6, 0xa6ccb436a3c72fa4})},
- {Sign::POS, -140, MType({0x8e4950fa5c943bbf, 0xc29b023fdcb2dccf})},
- {Sign::POS, -140, MType({0x20fa8a73c585f634, 0xde69bf8f58005dfc})},
- {Sign::POS, -140, MType({0xaa106d9b0a9717a, 0xfa38ec28905810a3})},
- {Sign::POS, -139, MType({0x85d70e032de41aec, 0x8b04440780460c2a})},
- {Sign::POS, -139, MType({0xbeee21cbb82a9a78, 0x98ec49a311cc30ab})},
- {Sign::POS, -139, MType({0xabd7b0fdd8efe6f6, 0xa6d486e8ba5151a0})},
- {Sign::POS, -139, MType({0x3221c56e2c1aa912, 0xb4bcfbda377d31cc})},
- {Sign::POS, -139, MType({0x57b795a36d9c5f19, 0xc2a5a879470c7c37})},
- {Sign::POS, -139, MType({0x131ec142c053ac3b, 0xd08e8cc7a6d0c580})},
- {Sign::POS, -139, MType({0x35e3298f4bb2aa0a, 0xde77a8c714b08d28})},
- {Sign::POS, -139, MType({0x7133dafdfc44f160, 0xec60fc794ea73ee4})},
- {Sign::POS, -139, MType({0x74b37d23121c59d5, 0xfa4a87e012c533eb})},
- {Sign::POS, -138, MType({0x93bf5f4207da8a4c, 0x841a257e8f97da22})},
- {Sign::POS, -138, MType({0xfdb5990ec6057f4e, 0x8b0f22e919107c0c})},
- {Sign::POS, -138, MType({0x2d408a58b1b202fe, 0x92043c3084f41481})},
- {Sign::POS, -138, MType({0x1759381b61dfbf01, 0x98f97155b274b1ab})},
- {Sign::POS, -138, MType({0x41e90a054df4b9f1, 0x9feec25980cedbbe})},
- {Sign::POS, -138, MType({0xa1e66c6203725d50, 0xa6e42f3ccf49959d})},
- {Sign::POS, -138, MType({0x8693d36ab45bd7ce, 0xadd9b8007d365d83})},
- {Sign::POS, -138, MType({0x91e25bb40ad3f098, 0xb4cf5ca569f12da9})},
- {Sign::POS, -138, MType({0xbdf94392c4cc7f6c, 0xbbc51d2c74e07cf0})},
- {Sign::POS, -138, MType({0x6fe37973354a82f9, 0xc2baf9967d753f89})},
- {Sign::POS, -138, MType({0x97647b4267bfd801, 0xc9b0f1e4632ae79b})},
- {Sign::POS, -138, MType({0xdbf5c32a454f7bdf, 0xd0a70617058765ee})},
- {Sign::POS, -138, MType({0xd6edfe04c37ba916, 0xd79d362f441b2a92})},
- {Sign::POS, -138, MType({0x5ad3480ccfbe9890, 0xde93822dfe812587})},
- {Sign::POS, -138, MType({0xc7d9ac765be7e325, 0xe589ea14145ec764})},
- {Sign::POS, -138, MType({0x6d8f24b9a3ca011b, 0xec806de265640204})},
- {Sign::POS, -138, MType({0xf9b654807dcdd5b2, 0xf3770d99d14b4928})},
- {Sign::POS, -138, MType({0xf4513f4745663028, 0xfa6dc93b37d99326})},
- {Sign::POS, -137, MType({0xa46e9a72d80da75f, 0x80b25063bc6f2cc6})},
- {Sign::POS, -137, MType({0xee60992b51ffac4b, 0x842dca1fba19cce6})},
- {Sign::POS, -137, MType({0x1977fa1c786886b3, 0x87a951d204deeaf3})},
- {Sign::POS, -137, MType({0xe5f7c52cdf119d5, 0x8b24e77b0cb60a84})},
- {Sign::POS, -137, MType({0x3bf9d70da1021a10, 0x8ea08b1b419bf221})},
- {Sign::POS, -137, MType({0xfd0406b07523b8e6, 0x921c3cb31392ab94})},
- {Sign::POS, -137, MType({0x453ee32c020f2a8, 0x9597fc42f2a18441})},
- {Sign::POS, -137, MType({0xcfb3ec22066bf7f6, 0x9913c9cb4ed50d72})},
- {Sign::POS, -137, MType({0x215c025bd493ecf9, 0x9c8fa54c983f1cb8})},
- {Sign::POS, -137, MType({0x39c116b7ee3a83ec, 0x9f2c93192e68232b})},
- {Sign::POS, -137, MType({0xf41f4b3ede2782f0, 0xa2a8870f24ac5f66})},
- {Sign::POS, -137, MType({0x61196927723eb75c, 0xa62488ff3c735799})},
- {Sign::POS, -137, MType({0xe615e836cb1edab, 0xa9a098e9e5e2a432})},
- {Sign::POS, -137, MType({0x6981331c5fc71cfc, 0xad1cb6cf91252372})},
- {Sign::POS, -137, MType({0x5f6a4faa054f11fa, 0xb098e2b0ae6af9c2})},
- {Sign::POS, -137, MType({0x2a68bc681a74c28, 0xb4151c8dade99205})},
- {Sign::POS, -137, MType({0x382ba24d90566403, 0xb7916466ffdb9ded})},
- {Sign::POS, -137, MType({0x6ad1abe51dd22e00, 0xbb0dba3d14811652})},
- {Sign::POS, -137, MType({0x456d3f7f59b13960, 0xbe8a1e105c1f3b85})},
- {Sign::POS, -137, MType({0x738dd8b7d66e9058, 0xc2068fe1470095a4})},
- {Sign::POS, -137, MType({0x68e123fed7ff11c6, 0xc5830fb04574f4f1})},
- {Sign::POS, -137, MType({0x2f3bd09780c3aa11, 0xc8ff9d7dc7d17225})},
- {Sign::POS, -137, MType({0x3b48887f1ce36935, 0xcc7c394a3e706ec5})},
- {Sign::POS, -137, MType({0x47ddae655ecc4633, 0xcff8e31619b19578})},
- {Sign::POS, -137, MType({0x37fa81eef4819c88, 0xd3759ae1c9f9da5b})},
- {Sign::POS, -137, MType({0xff6c4a8d747c65ed, 0xd6f260adbfb37b55})},
- {Sign::POS, -137, MType({0x921c29493a33318c, 0xda6f347a6b4e0070})},
- {Sign::POS, -137, MType({0xda0631eb65e731d8, 0xddec16483d3e3c27})},
- {Sign::POS, -137, MType({0xb3da6c07d110babc, 0xe1690617a5fe4bc2})},
- {Sign::POS, -137, MType({0xf2485c7868b8835a, 0xe4e603e9160d97a6})},
- {Sign::POS, -137, MType({0x67f5b7ed01344055, 0xe8630fbcfdf0d3ae})},
- {Sign::POS, -137, MType({0xf820df445b1d0622, 0xebe02993ce31ff7b})},
- {Sign::POS, -137, MType({0xadefc674b7eca5cd, 0xef5d516df76066d0})},
- {Sign::POS, -137, MType({0xda6be6dc057d3235, 0xf2da874bea10a1e0})},
- {Sign::POS, -137, MType({0x392bdde152ab5ff5, 0xf657cb2e16dc95a9})},
- {Sign::POS, -137, MType({0x1bab58e2ec99cf73, 0xf9d51d14ee637444})},
- {Sign::POS, -137, MType({0x9b51ef7e3388d692, 0xfd527d00e149bd3e})},
- {Sign::POS, -136, MType({0xe914c6a7f3f22fa2, 0x8067f579301c9ef6})},
- {Sign::POS, -136, MType({0xd22862eb2081c94, 0x8226b374edf088e2})},
- {Sign::POS, -136, MType({0x29ebd0b476cd8fd8, 0x83e57873e27ad153})},
- {Sign::POS, -136, MType({0x98feddc2806d01ed, 0x85a44476461854a0})},
- {Sign::POS, -136, MType({0x471bfc261a401854, 0x8763177c512896af})},
- {Sign::POS, -136, MType({0xb6f89c19b4cd1acd, 0x88b23a5b61430a16})},
- {Sign::POS, -136, MType({0xb39aaf34163fb099, 0x8a7119a85909ebe9})},
- {Sign::POS, -136, MType({0x1665f0f821541c36, 0x8c2ffff99357e887})},
- {Sign::POS, -136, MType({0xa5051754e049c1cb, 0x8deeed4f489679a6})},
- {Sign::POS, -136, MType({0x8c5a9a1c57b2e986, 0x8fade1a9b131c159})},
- {Sign::POS, -136, MType({0x1d8448438a26a9ae, 0x916cdd0905988a35})},
- {Sign::POS, -136, MType({0x8e3a0913ecd2fd02, 0x932bdf6d7e3c477d})},
- {Sign::POS, -136, MType({0xbc881a45f47f1d36, 0x94eae8d753911550})},
- {Sign::POS, -136, MType({0xf5e51c05499b06d0, 0x96a9f946be0db8d0})},
- {Sign::POS, -136, MType({0xc1a43be81a243fde, 0x986910bbf62ba04f})},
- {Sign::POS, -136, MType({0xaec3cfebe971beb7, 0x9a282f373466e378})},
- {Sign::POS, -136, MType({0x2518b29328614989, 0x9be754b8b13e437c})},
- {Sign::POS, -136, MType({0x39d6b147cbe803a4, 0x9da68140a5332b3a})},
- {Sign::POS, -136, MType({0x87765e3004ae428d, 0x9f65b4cf48c9af6d})},
- {Sign::POS, -136, MType({0x8f896ab28245bac, 0xa124ef64d4888ed6})},
- {Sign::POS, -136, MType({0xf8880fb5ca630c87, 0xa2e4310180f93263})},
- {Sign::POS, -136, MType({0xb179397cf82e935c, 0xa4a379a586a7ad62})},
- {Sign::POS, -136, MType({0x95a8cb717197ad81, 0xa662c9511e22bda3})},
- {Sign::POS, -136, MType({0xf6394a34b7f9a4a4, 0xa82220047ffbcba8})},
- {Sign::POS, -136, MType({0xffafd8c2b57884e8, 0xa9e17dbfe4c6ead0})},
- {Sign::POS, -136, MType({0xa970a643b8a6ac2b, 0xaba0e283851ad980})},
- {Sign::POS, -136, MType({0xa89b49fb749d47e0, 0xad604e4f9991014e})},
- {Sign::POS, -136, MType({0x66475ed2ac983305, 0xaf1fc1245ac5772e})},
- {Sign::POS, -136, MType({0xb4fd6209364bb36f, 0xb06f5be1bf1918e7})},
- {Sign::POS, -136, MType({0x8b5ce79b0965962a, 0xb22edb0636da31d6})},
- {Sign::POS, -136, MType({0x6724232b07396427, 0xb3ee6133f7149769})},
- {Sign::POS, -136, MType({0x2f02b14dcad8a49c, 0xb5adee6b386e62ae})},
- {Sign::POS, -136, MType({0xbd6443a81f792e07, 0xb76d82ac339058db})},
- {Sign::POS, -136, MType({0xea1cd9625749939a, 0xb92d1df72125eb7c})},
- {Sign::POS, -136, MType({0x97775e3142198913, 0xbaecc04c39dd389b})},
- {Sign::POS, -136, MType({0xc2a701b809a2bc39, 0xbcac69abb6670aeb})},
- {Sign::POS, -136, MType({0x979b990f39e662e3, 0xbe6c1a15cf76d9f6})},
- {Sign::POS, -136, MType({0x88395c463ddd82b2, 0xc02bd18abdc2ca45})},
- {Sign::POS, -136, MType({0x66f451bd9ba5ed05, 0xc1eb900aba03ad8d})},
- {Sign::POS, -136, MType({0x84cfb9413f6437a6, 0xc3ab5595fcf502d9})},
- {Sign::POS, -136, MType({0xd2c1c8d32943ca42, 0xc56b222cbf54f6b6})},
- {Sign::POS, -136, MType({0x67c0d1fd95192e6, 0xc72af5cf39e4635f})},
- {Sign::POS, -136, MType({0xc298bf9edb6441f2, 0xc8ead07da566d0e3})},
- {Sign::POS, -136, MType({0xc22d646addde3910, 0xcaaab2383aa27559})},
- {Sign::POS, -136, MType({0x7c301e5c7d1ca40, 0xcc6a9aff32603504})},
- {Sign::POS, -136, MType({0xfb444464df02505, 0xce2a8ad2c56ba27f})},
- {Sign::POS, -136, MType({0x5f1df3591ae898f, 0xcfea81b32c92feec})},
- {Sign::POS, -136, MType({0xb43caf8e7b891066, 0xd13a7f7c07506f7d})},
- {Sign::POS, -136, MType({0x597fb13f0d0fdf19, 0xd2fa82b36a610c4f})},
- {Sign::POS, -136, MType({0x3c21f1c60a60b0d6, 0xd4ba8cf83dd2a06b})},
- {Sign::POS, -136, MType({0x2b7455909a0428a4, 0xd67a9e4aba7d7ce5})},
- {Sign::POS, -136, MType({0x1438b60573d2da10, 0xd83ab6ab193ca223})},
- {Sign::POS, -136, MType({0x49f86400c5ab2b11, 0xd9fad61992edc008})},
- {Sign::POS, -136, MType({0xd3c313d148a23c35, 0xdbbafc9660713620})},
- {Sign::POS, -136, MType({0xbc56852355e0f0d5, 0xdd7b2a21baaa13cc})},
+ {Sign::NEG, -137, 0xdeca7290'13cd7c31'7f1ce002'fa34131b_u128},
+ {Sign::NEG, -137, 0xdb5475b4'4946d986'639afa08'5dd8b4c7_u128},
+ {Sign::NEG, -137, 0xd7de6b0e'10cab7d2'05512632'fe9a58cb_u128},
+ {Sign::NEG, -137, 0xd468529c'fc6fb395'b5380a99'53117d07_u128},
+ {Sign::NEG, -137, 0xd0f22c60'9e474741'70af2d7d'53be1f31_u128},
+ {Sign::NEG, -137, 0xcd7bf858'885dcae2'0ccd499c'49b74cc2_u128},
+ {Sign::NEG, -137, 0xca05b684'4cba73cf'5b51ddc3'987ebfb8_u128},
+ {Sign::NEG, -137, 0xc68f66e3'7d5f545a'49375f51'89b3782b_u128},
+ {Sign::NEG, -137, 0xc3190975'ac495b7a'f6e57738'865c712f_u128},
+ {Sign::NEG, -137, 0xbfa29e3a'6b70547e'ca02b10a'8c712acd_u128},
+ {Sign::NEG, -137, 0xbc2c2531'4cc6e6b6'78e50382'10208151_u128},
+ {Sign::NEG, -137, 0xb8b59e59'e23a9524'0fa099ec'd71ee0ea_u128},
+ {Sign::NEG, -137, 0xb53f09b3'bdb3be28'eeb445cc'b8fb09ed_u128},
+ {Sign::NEG, -137, 0xb1c8673e'71159b33'c352fff1'8a1c02fb_u128},
+ {Sign::NEG, -137, 0xae51b6f9'8e3e406e'7949e03e'cf9b390b_u128},
+ {Sign::NEG, -137, 0xaadaf8e4'a7069c6c'2681f33f'30aadedc_u128},
+ {Sign::NEG, -137, 0xa7642cff'4d4277d6'f01d5496'eea213b3_u128},
+ {Sign::NEG, -137, 0xa3ed5349'12c0751d'e92ef555'ff1de975_u128},
+ {Sign::NEG, -137, 0xa0766bc1'894a1022'eb0c7519'b3e7c1e0_u128},
+ {Sign::NEG, -137, 0x9c21b6e9'1e7f03a3'f60d204f'f0fe5296_u128},
+ {Sign::NEG, -137, 0x98aab049'1050bea8'125c19a4'f057c18b_u128},
+ {Sign::NEG, -137, 0x95339bd6'4cd953e7'7e9383ce'1bdf9575_u128},
+ {Sign::NEG, -137, 0x91bc7990'65cc57d6'bf274f4d'8f770253_u128},
+ {Sign::NEG, -137, 0x8e454976'ecd836ad'656bd9b7'58fe44ba_u128},
+ {Sign::NEG, -137, 0x8ace0b89'73a63413'bfdd2c7f'388fc014_u128},
+ {Sign::NEG, -137, 0x8756bfc7'8bda6ad0'83fbf6ed'936c493a_u128},
+ {Sign::NEG, -137, 0x83df6630'c713cc76'71bfa9a1'8bec01cc_u128},
+ {Sign::NEG, -137, 0x8067fec4'b6ec2111'f09d19f5'6dbfef72_u128},
+ {Sign::NEG, -138, 0xf9e11305'd9f00dad'4c422713'b1642228_u128},
+ {Sign::NEG, -138, 0xf2f20cd5'f58de39a'0c3c7c56'99b7a0a4_u128},
+ {Sign::NEG, -138, 0xec02eaf8'e3c656ff'b8db7c69'e3fa0797_u128},
+ {Sign::NEG, -138, 0xe513ad6d'c7a3a553'a083eb05'506ff7ed_u128},
+ {Sign::NEG, -138, 0xde245433'c425b5c5'c21595e7'45f1fa15_u128},
+ {Sign::NEG, -138, 0xd734df49'fc42189b'b9d5bcdb'fe719389_u128},
+ {Sign::NEG, -138, 0xd0454eaf'92e4068b'a17a1e85'e93461f4_u128},
+ {Sign::NEG, -138, 0xc955a263'aaec6016'e3537584'da333fda_u128},
+ {Sign::NEG, -138, 0xc265da65'6731ace5'00963177'f24682c2_u128},
+ {Sign::NEG, -138, 0xbb75f6b3'ea801b1e'4ac03734'7bcfc50e_u128},
+ {Sign::NEG, -138, 0xb485f74e'57997ec6'901a736a'4364cdfd_u128},
+ {Sign::NEG, -138, 0xad95dc33'd1355117'bb550acc'3b9d7247_u128},
+ {Sign::NEG, -138, 0xa6a5a563'7a00afdc'663cf2b2'7e8f1ffb_u128},
+ {Sign::NEG, -138, 0x9fb552dc'749e5cca'5f89bd08'feb39952_u128},
+ {Sign::NEG, -138, 0x98c4e49d'e3a6bcdd'23c2623c'73f494db_u128},
+ {Sign::NEG, -138, 0x91d45aa6'e9a7d7b0'4937d3b5'485af61e_u128},
+ {Sign::NEG, -138, 0x8ae3b4f6'a92556d9'df14214e'7a6d8111_u128},
+ {Sign::NEG, -138, 0x83f2f38c'44988544'bf7cfc14'999fb4bc_u128},
+ {Sign::NEG, -139, 0xfa042ccd'bce09d15'a990c0ee'569a8d51_u128},
+ {Sign::NEG, -139, 0xec223b0b'32227c9e'a38463e9'd941e1c2_u128},
+ {Sign::NEG, -139, 0xde4011cf'2daaff31'ba032453'0edaa03f_u128},
+ {Sign::NEG, -139, 0xd05db117'f419b857'5e997a02'dad7ace7_u128},
+ {Sign::NEG, -139, 0xc27b18e3'c9f977c7'4a14676d'4d0f817e_u128},
+ {Sign::NEG, -139, 0xb4984930'f3c0481c'857c002e'e7a1e473_u128},
+ {Sign::NEG, -139, 0xa6b541fd'b5cf6d89'5923b2eb'72d8012a_u128},
+ {Sign::NEG, -139, 0x98d20348'5473648b'21cde8f8'5ca1f9fd_u128},
+ {Sign::NEG, -139, 0x8aee8d0f'13e3e09e'0be08e08'b1d212d4_u128},
+ {Sign::NEG, -140, 0xfa15bea0'708795e1'69502399'8e6bd7b0_u128},
+ {Sign::NEG, -140, 0xde4df414'0b42822f'634cea67'50617a92_u128},
+ {Sign::NEG, -140, 0xc285ba75'7feb2781'fbd7e970'aef9dbb8_u128},
+ {Sign::NEG, -140, 0xa6bd11c1'564a8ace'9aedc1c1'ba7d0695_u128},
+ {Sign::NEG, -140, 0x8af3f9f4'1600120a'8d306ba2'07233c44_u128},
+ {Sign::NEG, -141, 0xde54e614'8d030322'856a0a3a'00fcf3c1_u128},
+ {Sign::NEG, -141, 0xa6c0fa00'de35f314'b3a2c140'7cf6d38d_u128},
+ {Sign::NEG, -142, 0xde585f4c'5bbbcd3d'd791cf6a'70c3a504_u128},
+ {Sign::NEG, -143, 0xde5a1bf6'27b1f68f'10a633f2'c4a8ea22_u128},
+ {Sign::NEG, 0, 0_u128},
+ {Sign::POS, -143, 0xde5d9565'8a729eab'ed4a68e5'e6e83ddf_u128},
+ {Sign::POS, -142, 0xde5f522b'21e3e25a'3281f187'2cdbee94_u128},
+ {Sign::POS, -141, 0xa6c8cb3b'7e5bbbfd'f1466eda'a96e356e_u128},
+ {Sign::POS, -141, 0xde62cbd2'1e895473'8a607fd6'95dfc3d9_u128},
+ {Sign::POS, -140, 0x8afed570'32bebc7c'c36b8713'ceefe2de_u128},
+ {Sign::POS, -140, 0xa6ccb436'a3c72fa4'5c2e76c9'53e3e3e6_u128},
+ {Sign::POS, -140, 0xc29b023f'dcb2dccf'8e4950fa'5c943bbf_u128},
+ {Sign::POS, -140, 0xde69bf8f'58005dfc'20fa8a73'c585f634_u128},
+ {Sign::POS, -140, 0xfa38ec28'905810a3'0aa106d9'b0a9717a_u128},
+ {Sign::POS, -139, 0x8b044407'80460c2a'85d70e03'2de41aec_u128},
+ {Sign::POS, -139, 0x98ec49a3'11cc30ab'beee21cb'b82a9a78_u128},
+ {Sign::POS, -139, 0xa6d486e8'ba5151a0'abd7b0fd'd8efe6f6_u128},
+ {Sign::POS, -139, 0xb4bcfbda'377d31cc'3221c56e'2c1aa912_u128},
+ {Sign::POS, -139, 0xc2a5a879'470c7c37'57b795a3'6d9c5f19_u128},
+ {Sign::POS, -139, 0xd08e8cc7'a6d0c580'131ec142'c053ac3b_u128},
+ {Sign::POS, -139, 0xde77a8c7'14b08d28'35e3298f'4bb2aa0a_u128},
+ {Sign::POS, -139, 0xec60fc79'4ea73ee4'7133dafd'fc44f160_u128},
+ {Sign::POS, -139, 0xfa4a87e0'12c533eb'74b37d23'121c59d5_u128},
+ {Sign::POS, -138, 0x841a257e'8f97da22'93bf5f42'07da8a4c_u128},
+ {Sign::POS, -138, 0x8b0f22e9'19107c0c'fdb5990e'c6057f4e_u128},
+ {Sign::POS, -138, 0x92043c30'84f41481'2d408a58'b1b202fe_u128},
+ {Sign::POS, -138, 0x98f97155'b274b1ab'1759381b'61dfbf01_u128},
+ {Sign::POS, -138, 0x9feec259'80cedbbe'41e90a05'4df4b9f1_u128},
+ {Sign::POS, -138, 0xa6e42f3c'cf49959d'a1e66c62'03725d50_u128},
+ {Sign::POS, -138, 0xadd9b800'7d365d83'8693d36a'b45bd7ce_u128},
+ {Sign::POS, -138, 0xb4cf5ca5'69f12da9'91e25bb4'0ad3f098_u128},
+ {Sign::POS, -138, 0xbbc51d2c'74e07cf0'bdf94392'c4cc7f6c_u128},
+ {Sign::POS, -138, 0xc2baf996'7d753f89'6fe37973'354a82f9_u128},
+ {Sign::POS, -138, 0xc9b0f1e4'632ae79b'97647b42'67bfd801_u128},
+ {Sign::POS, -138, 0xd0a70617'058765ee'dbf5c32a'454f7bdf_u128},
+ {Sign::POS, -138, 0xd79d362f'441b2a92'd6edfe04'c37ba916_u128},
+ {Sign::POS, -138, 0xde93822d'fe812587'5ad3480c'cfbe9890_u128},
+ {Sign::POS, -138, 0xe589ea14'145ec764'c7d9ac76'5be7e325_u128},
+ {Sign::POS, -138, 0xec806de2'65640204'6d8f24b9'a3ca011b_u128},
+ {Sign::POS, -138, 0xf3770d99'd14b4928'f9b65480'7dcdd5b2_u128},
+ {Sign::POS, -138, 0xfa6dc93b'37d99326'f4513f47'45663028_u128},
+ {Sign::POS, -137, 0x80b25063'bc6f2cc6'a46e9a72'd80da75f_u128},
+ {Sign::POS, -137, 0x842dca1f'ba19cce6'ee60992b'51ffac4b_u128},
+ {Sign::POS, -137, 0x87a951d2'04deeaf3'1977fa1c'786886b3_u128},
+ {Sign::POS, -137, 0x8b24e77b'0cb60a84'0e5f7c52'cdf119d5_u128},
+ {Sign::POS, -137, 0x8ea08b1b'419bf221'3bf9d70d'a1021a10_u128},
+ {Sign::POS, -137, 0x921c3cb3'1392ab94'fd0406b0'7523b8e6_u128},
+ {Sign::POS, -137, 0x9597fc42'f2a18441'0453ee32'c020f2a8_u128},
+ {Sign::POS, -137, 0x9913c9cb'4ed50d72'cfb3ec22'066bf7f6_u128},
+ {Sign::POS, -137, 0x9c8fa54c'983f1cb8'215c025b'd493ecf9_u128},
+ {Sign::POS, -137, 0x9f2c9319'2e68232b'39c116b7'ee3a83ec_u128},
+ {Sign::POS, -137, 0xa2a8870f'24ac5f66'f41f4b3e'de2782f0_u128},
+ {Sign::POS, -137, 0xa62488ff'3c735799'61196927'723eb75c_u128},
+ {Sign::POS, -137, 0xa9a098e9'e5e2a432'0e615e83'6cb1edab_u128},
+ {Sign::POS, -137, 0xad1cb6cf'91252372'6981331c'5fc71cfc_u128},
+ {Sign::POS, -137, 0xb098e2b0'ae6af9c2'5f6a4faa'054f11fa_u128},
+ {Sign::POS, -137, 0xb4151c8d'ade99205'02a68bc6'81a74c28_u128},
+ {Sign::POS, -137, 0xb7916466'ffdb9ded'382ba24d'90566403_u128},
+ {Sign::POS, -137, 0xbb0dba3d'14811652'6ad1abe5'1dd22e00_u128},
+ {Sign::POS, -137, 0xbe8a1e10'5c1f3b85'456d3f7f'59b13960_u128},
+ {Sign::POS, -137, 0xc2068fe1'470095a4'738dd8b7'd66e9058_u128},
+ {Sign::POS, -137, 0xc5830fb0'4574f4f1'68e123fe'd7ff11c6_u128},
+ {Sign::POS, -137, 0xc8ff9d7d'c7d17225'2f3bd097'80c3aa11_u128},
+ {Sign::POS, -137, 0xcc7c394a'3e706ec5'3b48887f'1ce36935_u128},
+ {Sign::POS, -137, 0xcff8e316'19b19578'47ddae65'5ecc4633_u128},
+ {Sign::POS, -137, 0xd3759ae1'c9f9da5b'37fa81ee'f4819c88_u128},
+ {Sign::POS, -137, 0xd6f260ad'bfb37b55'ff6c4a8d'747c65ed_u128},
+ {Sign::POS, -137, 0xda6f347a'6b4e0070'921c2949'3a33318c_u128},
+ {Sign::POS, -137, 0xddec1648'3d3e3c27'da0631eb'65e731d8_u128},
+ {Sign::POS, -137, 0xe1690617'a5fe4bc2'b3da6c07'd110babc_u128},
+ {Sign::POS, -137, 0xe4e603e9'160d97a6'f2485c78'68b8835a_u128},
+ {Sign::POS, -137, 0xe8630fbc'fdf0d3ae'67f5b7ed'01344055_u128},
+ {Sign::POS, -137, 0xebe02993'ce31ff7b'f820df44'5b1d0622_u128},
+ {Sign::POS, -137, 0xef5d516d'f76066d0'adefc674'b7eca5cd_u128},
+ {Sign::POS, -137, 0xf2da874b'ea10a1e0'da6be6dc'057d3235_u128},
+ {Sign::POS, -137, 0xf657cb2e'16dc95a9'392bdde1'52ab5ff5_u128},
+ {Sign::POS, -137, 0xf9d51d14'ee637444'1bab58e2'ec99cf73_u128},
+ {Sign::POS, -137, 0xfd527d00'e149bd3e'9b51ef7e'3388d692_u128},
+ {Sign::POS, -136, 0x8067f579'301c9ef6'e914c6a7'f3f22fa2_u128},
+ {Sign::POS, -136, 0x8226b374'edf088e2'0d22862e'b2081c94_u128},
+ {Sign::POS, -136, 0x83e57873'e27ad153'29ebd0b4'76cd8fd8_u128},
+ {Sign::POS, -136, 0x85a44476'461854a0'98feddc2'806d01ed_u128},
+ {Sign::POS, -136, 0x8763177c'512896af'471bfc26'1a401854_u128},
+ {Sign::POS, -136, 0x88b23a5b'61430a16'b6f89c19'b4cd1acd_u128},
+ {Sign::POS, -136, 0x8a7119a8'5909ebe9'b39aaf34'163fb099_u128},
+ {Sign::POS, -136, 0x8c2ffff9'9357e887'1665f0f8'21541c36_u128},
+ {Sign::POS, -136, 0x8deeed4f'489679a6'a5051754'e049c1cb_u128},
+ {Sign::POS, -136, 0x8fade1a9'b131c159'8c5a9a1c'57b2e986_u128},
+ {Sign::POS, -136, 0x916cdd09'05988a35'1d844843'8a26a9ae_u128},
+ {Sign::POS, -136, 0x932bdf6d'7e3c477d'8e3a0913'ecd2fd02_u128},
+ {Sign::POS, -136, 0x94eae8d7'53911550'bc881a45'f47f1d36_u128},
+ {Sign::POS, -136, 0x96a9f946'be0db8d0'f5e51c05'499b06d0_u128},
+ {Sign::POS, -136, 0x986910bb'f62ba04f'c1a43be8'1a243fde_u128},
+ {Sign::POS, -136, 0x9a282f37'3466e378'aec3cfeb'e971beb7_u128},
+ {Sign::POS, -136, 0x9be754b8'b13e437c'2518b293'28614989_u128},
+ {Sign::POS, -136, 0x9da68140'a5332b3a'39d6b147'cbe803a4_u128},
+ {Sign::POS, -136, 0x9f65b4cf'48c9af6d'87765e30'04ae428d_u128},
+ {Sign::POS, -136, 0xa124ef64'd4888ed6'08f896ab'28245bac_u128},
+ {Sign::POS, -136, 0xa2e43101'80f93263'f8880fb5'ca630c87_u128},
+ {Sign::POS, -136, 0xa4a379a5'86a7ad62'b179397c'f82e935c_u128},
+ {Sign::POS, -136, 0xa662c951'1e22bda3'95a8cb71'7197ad81_u128},
+ {Sign::POS, -136, 0xa8222004'7ffbcba8'f6394a34'b7f9a4a4_u128},
+ {Sign::POS, -136, 0xa9e17dbf'e4c6ead0'ffafd8c2'b57884e8_u128},
+ {Sign::POS, -136, 0xaba0e283'851ad980'a970a643'b8a6ac2b_u128},
+ {Sign::POS, -136, 0xad604e4f'9991014e'a89b49fb'749d47e0_u128},
+ {Sign::POS, -136, 0xaf1fc124'5ac5772e'66475ed2'ac983305_u128},
+ {Sign::POS, -136, 0xb06f5be1'bf1918e7'b4fd6209'364bb36f_u128},
+ {Sign::POS, -136, 0xb22edb06'36da31d6'8b5ce79b'0965962a_u128},
+ {Sign::POS, -136, 0xb3ee6133'f7149769'6724232b'07396427_u128},
+ {Sign::POS, -136, 0xb5adee6b'386e62ae'2f02b14d'cad8a49c_u128},
+ {Sign::POS, -136, 0xb76d82ac'339058db'bd6443a8'1f792e07_u128},
+ {Sign::POS, -136, 0xb92d1df7'2125eb7c'ea1cd962'5749939a_u128},
+ {Sign::POS, -136, 0xbaecc04c'39dd389b'97775e31'42198913_u128},
+ {Sign::POS, -136, 0xbcac69ab'b6670aeb'c2a701b8'09a2bc39_u128},
+ {Sign::POS, -136, 0xbe6c1a15'cf76d9f6'979b990f'39e662e3_u128},
+ {Sign::POS, -136, 0xc02bd18a'bdc2ca45'88395c46'3ddd82b2_u128},
+ {Sign::POS, -136, 0xc1eb900a'ba03ad8d'66f451bd'9ba5ed05_u128},
+ {Sign::POS, -136, 0xc3ab5595'fcf502d9'84cfb941'3f6437a6_u128},
+ {Sign::POS, -136, 0xc56b222c'bf54f6b6'd2c1c8d3'2943ca42_u128},
+ {Sign::POS, -136, 0xc72af5cf'39e4635f'067c0d1f'd95192e6_u128},
+ {Sign::POS, -136, 0xc8ead07d'a566d0e3'c298bf9e'db6441f2_u128},
+ {Sign::POS, -136, 0xcaaab238'3aa27559'c22d646a'ddde3910_u128},
+ {Sign::POS, -136, 0xcc6a9aff'32603504'07c301e5'c7d1ca40_u128},
+ {Sign::POS, -136, 0xce2a8ad2'c56ba27f'0fb44446'4df02505_u128},
+ {Sign::POS, -136, 0xcfea81b3'2c92feec'05f1df35'91ae898f_u128},
+ {Sign::POS, -136, 0xd13a7f7c'07506f7d'b43caf8e'7b891066_u128},
+ {Sign::POS, -136, 0xd2fa82b3'6a610c4f'597fb13f'0d0fdf19_u128},
+ {Sign::POS, -136, 0xd4ba8cf8'3dd2a06b'3c21f1c6'0a60b0d6_u128},
+ {Sign::POS, -136, 0xd67a9e4a'ba7d7ce5'2b745590'9a0428a4_u128},
+ {Sign::POS, -136, 0xd83ab6ab'193ca223'1438b605'73d2da10_u128},
+ {Sign::POS, -136, 0xd9fad619'92edc008'49f86400'c5ab2b11_u128},
+ {Sign::POS, -136, 0xdbbafc96'60713620'd3c313d1'48a23c35_u128},
+ {Sign::POS, -136, 0xdd7b2a21'baaa13cc'bc568523'55e0f0d5_u128},
},
// -log10(r) for the third step, generated by SageMath with:
//
// for i in range(-80, 81):
// r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent();
- // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, "," ,
+ // format_hex(m), "},");
/* .step_3 = */
{
- {Sign::NEG, -143, MType({0x54d7e49898ca0093, 0x8af8b9b322ba8c7d})},
- {Sign::NEG, -143, MType({0xc321bbf16665f29c, 0x893c06529deffc3d})},
- {Sign::NEG, -143, MType({0x8246df7140c3e4ae, 0x877f52e433ac7ec4})},
- {Sign::NEG, -143, MType({0x1deaa9e85780e4c1, 0x85c29f67e3ef35bc})},
- {Sign::NEG, -143, MType({0xcd8a5121a9162d0, 0x8405ebddaeb742cf})},
- {Sign::NEG, -143, MType({0xb10486fa4644308d, 0x824938459403c7a7})},
- {Sign::NEG, -143, MType({0x578a2f61eedd4be8, 0x808c849f93d3e5f0})},
- {Sign::NEG, -144, MType({0x715b4a491790e8a7, 0xfd9fa1d75c4d7ea6})},
- {Sign::NEG, -144, MType({0xefb6273a04c71573, 0xfa263a53c5f6eaf4})},
- {Sign::NEG, -144, MType({0x474d901560c17807, 0xf6acd2b464a25420})},
- {Sign::NEG, -144, MType({0x6b9a5deceb80ec57, 0xf3336af9384dfd7c})},
- {Sign::NEG, -144, MType({0x2665a32f7cc64f79, 0xefba032240f82a5d})},
- {Sign::NEG, -144, MType({0x17c8a67316659363, 0xec409b2f7e9f1e16})},
- {Sign::NEG, -144, MType({0xb62cdd3ef5c8673d, 0xe8c73320f1411bfa})},
- {Sign::NEG, -144, MType({0x4e4be6d5a4a07422, 0xe54dcaf698dc675e})},
- {Sign::NEG, -144, MType({0x32f86ff08c92e22, 0xe1d462b0756f4394})},
- {Sign::NEG, -144, MType({0xce31a0d27359396f, 0xde5afa4e86f7f3ee})},
- {Sign::NEG, -144, MType({0x7efc3180aee36373, 0xdae191d0cd74bbc1})},
- {Sign::NEG, -144, MType({0xbb894b1e0ce72fc4, 0xd768293748e3de5e})},
- {Sign::NEG, -144, MType({0x230f6c7270f8be, 0xd3eec081f9439f19})},
- {Sign::NEG, -144, MType({0x9f63aaa563e9a399, 0xd07557b0de924142})},
- {Sign::NEG, -144, MType({0xc2354e441015e7eb, 0xccfbeec3f8ce082d})},
- {Sign::NEG, -144, MType({0x67d22bcf5a452a4c, 0xc98285bb47f5372c})},
- {Sign::NEG, -144, MType({0x65c46fa3e3afea18, 0xc6091c96cc061190})},
- {Sign::NEG, -144, MType({0x67e63bbe1405c20d, 0xc28fb35684fedaab})},
- {Sign::NEG, -144, MType({0xf061a284212afbad, 0xbf1649fa72ddd5ce})},
- {Sign::NEG, -144, MType({0x57b0a1901625b539, 0xbb9ce08295a1464c})},
- {Sign::NEG, -144, MType({0xcc9d1c79d93a9a1e, 0xb82376eeed476f74})},
- {Sign::NEG, -144, MType({0x5440d7a131392da8, 0xb4aa0d3f79ce9499})},
- {Sign::NEG, -144, MType({0xca0572f7c9f7a7de, 0xb130a3743b34f90a})},
- {Sign::NEG, -144, MType({0xdfa464cb37fe6455, 0xadb7398d3178e019})},
- {Sign::NEG, -144, MType({0x1d26f48efb62e2e0, 0xaa3dcf8a5c988d17})},
- {Sign::NEG, -144, MType({0xe0e635a681d259e2, 0xa6c4656bbc924352})},
- {Sign::NEG, -144, MType({0x5f8b022f27cbda35, 0xa34afb315164461d})},
- {Sign::NEG, -144, MType({0xa40df5ca390a0465, 0x9fd190db1b0cd8c6})},
- {Sign::NEG, -144, MType({0x8fb76866f01c4f2d, 0x9c582669198a3e9e})},
- {Sign::NEG, -144, MType({0xda1f690c752fdeff, 0x98debbdb4cdabaf4})},
- {Sign::NEG, -144, MType({0x112db8a3dc07ee78, 0x95655131b4fc9119})},
- {Sign::NEG, -144, MType({0x9919c4c22125c79e, 0x91ebe66c51ee045a})},
- {Sign::NEG, -144, MType({0xac6aa27226204db3, 0x8e727b8b23ad5808})},
- {Sign::NEG, -144, MType({0x5bf708fead2b1780, 0x8af9108e2a38cf72})},
- {Sign::NEG, -144, MType({0x8ee54cbc53cd19ed, 0x877fa575658eade6})},
- {Sign::NEG, -144, MType({0x2ab59d38cc6e2c5, 0x84063a40d5ad36b4})},
- {Sign::NEG, -144, MType({0x4b0eaf0a99286378, 0x808ccef07a92ad29})},
- {Sign::NEG, -145, MType({0xa448b11f012c975c, 0xfa26c708a87aa929})},
- {Sign::NEG, -145, MType({0xb0a1d584117de73b, 0xf333eff8c556e089})},
- {Sign::NEG, -145, MType({0xe890f9fb57fdabb6, 0xec4118b14bb6870e})},
- {Sign::NEG, -145, MType({0x261d48c71e693130, 0xe54e41323b962355})},
- {Sign::NEG, -145, MType({0xefecdd48ed894c32, 0xde5b697b94f23bf7})},
- {Sign::NEG, -145, MType({0x7944b9957598a88a, 0xd768918d57c75792})},
- {Sign::NEG, -145, MType({0xa208bc0875093645, 0xd075b9678411fcbf})},
- {Sign::NEG, -145, MType({0xf6bb94d89da8b432, 0xc982e10a19ceb219})},
- {Sign::NEG, -145, MType({0xb07ebbab782457b0, 0xc290087518f9fe3b})},
- {Sign::NEG, -145, MType({0xb512652945eb9165, 0xbb9d2fa8819067be})},
- {Sign::NEG, -145, MType({0x96d57890e171eea5, 0xb4aa56a4538e753c})},
- {Sign::NEG, -145, MType({0x94c5854b9cd01726, 0xadb77d688ef0ad4e})},
- {Sign::NEG, -145, MType({0x9a7eb8811ec3e6bb, 0xa6c4a3f533b3968d})},
- {Sign::NEG, -145, MType({0x403bd2ab3e0fa2d7, 0x9fd1ca4a41d3b792})},
- {Sign::NEG, -145, MType({0xcad61d29db384b6b, 0x98def067b94d96f4})},
- {Sign::NEG, -145, MType({0x2bc55fd6b8a306ec, 0x91ec164d9a1dbb4d})},
- {Sign::NEG, -145, MType({0x11fd6995111a927, 0x8af93bfbe440ab33})},
- {Sign::NEG, -145, MType({0x959a26faac7e5494, 0x8406617297b2ed3d})},
- {Sign::NEG, -146, MType({0xc10eab7266ac6bc0, 0xfa270d6368e21007})},
- {Sign::NEG, -146, MType({0xbb178b90026b2b2, 0xec41577274ef0439})},
- {Sign::NEG, -146, MType({0xac3bfd925e6b33e1, 0xde5ba1125385c43b})},
- {Sign::NEG, -146, MType({0x9d0a01a95b355319, 0xd075ea43049f5d3b})},
- {Sign::NEG, -146, MType({0x31b3b7b20a6a6496, 0xc29033048834dc64})},
- {Sign::NEG, -146, MType({0x170da891504620f4, 0xb4aa7b56de3f4ee0})},
- {Sign::NEG, -146, MType({0x53289e84744549cb, 0xa6c4c33a06b7c1d9})},
- {Sign::NEG, -146, MType({0x45519048b0ce7e7f, 0x98df0aae01974279})},
- {Sign::NEG, -146, MType({0xa6118c42bf99407e, 0x8af951b2ced6dde8})},
- {Sign::NEG, -147, MType({0xe5b474cc5a64cf6, 0xfa273090dcdf429f})},
- {Sign::NEG, -147, MType({0xa74dab3bd6067bc7, 0xde5bbcddc0b533aa})},
- {Sign::NEG, -147, MType({0x9f73f4e37357341b, 0xc290484c4921a941})},
- {Sign::NEG, -147, MType({0x31bf5d5f815220e7, 0xa6c4d2dc7616bdb0})},
- {Sign::NEG, -147, MType({0x4b987ca5fca242d7, 0x8af95c8e47868b41})},
- {Sign::NEG, -148, MType({0x19be3fabd93832c5, 0xde5bcac37ac6587d})},
- {Sign::NEG, -148, MType({0x8fd43f0c9ce444d3, 0xa6c4daadaf3d75e0})},
- {Sign::NEG, -149, MType({0x61cd853e796bc2c, 0xde5bd1b658ad4676})},
- {Sign::NEG, -150, MType({0x87d6afabfba0644f, 0xde5bd52fc7d8545f})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -150, MType({0xa9bf32001043629d, 0xde5bdc22a69d9e19})},
- {Sign::POS, -149, MType({0x8014f0f360272d82, 0xde5bdf9c1637d9ef})},
- {Sign::POS, -148, MType({0xfe94a02fc639c0e3, 0xa6c4ea5024795bd2})},
- {Sign::POS, -148, MType({0xbee710a5ace7c8d4, 0xde5be68ef5db7f99})},
- {Sign::POS, -147, MType({0x1a778d8100437e4f, 0x8af972453faf11e8})},
- {Sign::POS, -147, MType({0x97d773f8992f7051, 0xa6c4f221608e89fe})},
- {Sign::POS, -147, MType({0xc9ee5841a3afa95, 0xc29072dbdd9a0dd5})},
- {Sign::POS, -147, MType({0x7b644b13993cf4ef, 0xde5bf474b6df8331})},
- {Sign::POS, -147, MType({0x3448f66e2bd7a0ca, 0xfa2776ebec6ccfdb})},
- {Sign::POS, -146, MType({0x6a7ca5f1a87a1a3c, 0x8af97d20bf27eccd})},
- {Sign::POS, -146, MType({0x245675fe3061108f, 0x98df3f3ab64b431d})},
- {Sign::POS, -146, MType({0x64136e97019d0a3b, 0xa6c501c3dba75dc2})},
- {Sign::POS, -146, MType({0x6cdadac4d6925bd4, 0xb4aac4bc2f432fa3})},
- {Sign::POS, -146, MType({0x2899e23791d29632, 0xc2908823b125aba7})},
- {Sign::POS, -146, MType({0x28039e1f0323a4c1, 0xd0764bfa6155c4b5})},
- {Sign::POS, -146, MType({0xa2912e03afc8cc28, 0xde5c10403fda6db5})},
- {Sign::POS, -146, MType({0x7681cc9f9e0d89f9, 0xec41d4f54cba9991})},
- {Sign::POS, -146, MType({0x28dae4b7241255e1, 0xfa279a1987fd3b32})},
- {Sign::POS, -145, MType({0xf2b412f8dceda28e, 0x8406afd678d4a2c0})},
- {Sign::POS, -145, MType({0xbf5dccd967504857, 0x8af992d7c4e2d5b5})},
- {Sign::POS, -145, MType({0x3716dbf950b07f85, 0x91ec7610a82cafed})},
- {Sign::POS, -145, MType({0x69eebe0b8e5b18e1, 0x98df598122b5aadd})},
- {Sign::POS, -145, MType({0xbb583ce65af56beb, 0x9fd23d2934813ffc})},
- {Sign::POS, -145, MType({0xe22978efa7a962a0, 0xa6c52108dd92e8c1})},
- {Sign::POS, -145, MType({0xe89bf3898ef27836, 0xadb805201dee1ea3})},
- {Sign::POS, -145, MType({0x2c4c997ec90bab0b, 0xb4aae96ef5965b1a})},
- {Sign::POS, -145, MType({0x5e3bcd6f21fe6224, 0xbb9dcdf5648f179c})},
- {Sign::POS, -145, MType({0x82cd723bf1524680, 0xc290b2b36adbcda2})},
- {Sign::POS, -145, MType({0xf1c8f574935e109b, 0xc98397a9087ff6a4})},
- {Sign::POS, -145, MType({0x565959c2e4394a59, 0xd0767cd63d7f0c1c})},
- {Sign::POS, -145, MType({0xaf0d4157bc4f05be, 0xd769623b09dc8781})},
- {Sign::POS, -145, MType({0x4dd6f8576e9188b8, 0xde5c47d76d9be24e})},
- {Sign::POS, -145, MType({0xd80c7f46484eee3d, 0xe54f2dab68c095fb})},
- {Sign::POS, -145, MType({0x4667957512a6bd26, 0xec4213b6fb4e1c04})},
- {Sign::POS, -145, MType({0xe505c36d95a074fa, 0xf334f9fa2547ede1})},
- {Sign::POS, -145, MType({0x5368655f1ce3110b, 0xfa27e074e6b1850f})},
- {Sign::POS, -144, MType({0xc23a5ac57f06c112, 0x808d63939fc72d83})},
- {Sign::POS, -144, MType({0xdf39eb5890580f93, 0x8406d70897f0f4a2})},
- {Sign::POS, -144, MType({0xcd896f3e43f38669, 0x87804a995bd7d4a2})},
- {Sign::POS, -144, MType({0x83b16ff7eecace8c, 0x8af9be45eb7d8a41})},
- {Sign::POS, -144, MType({0x21ec7ae8ffa1531d, 0x8e73320e46e3d23d})},
- {Sign::POS, -144, MType({0xf227268d464ae907, 0x91eca5f26e0c6953})},
- {Sign::POS, -144, MType({0x680017af3bbaf2d3, 0x956619f260f90c44})},
- {Sign::POS, -144, MType({0x20c8069e4ae400de, 0x98df8e0e1fab77cd})},
- {Sign::POS, -144, MType({0xe381c4651a67ee13, 0x9c590245aa2568ac})},
- {Sign::POS, -144, MType({0xa0e23fffd718794e, 0x9fd2769900689ba2})},
- {Sign::POS, -144, MType({0x73508b927f485b97, 0xa34beb082276cd6d})},
- {Sign::POS, -144, MType({0x9ee5e19f2eecdb55, 0xa6c55f931051bacc})},
- {Sign::POS, -144, MType({0x916daa3c6c8fdc9d, 0xaa3ed439c9fb207f})},
- {Sign::POS, -144, MType({0xe265804b77126ed3, 0xadb848fc4f74bb45})},
- {Sign::POS, -144, MType({0x52fd36ae943fd7b4, 0xb131bddaa0c047df})},
- {Sign::POS, -144, MType({0xce16dd7f60311bf6, 0xb4ab32d4bddf830b})},
- {Sign::POS, -144, MType({0x6846c7451d8105ac, 0xb824a7eaa6d4298b})},
- {Sign::POS, -144, MType({0x5fd38e2b0650a884, 0xbb9e1d1c5b9ff81e})},
- {Sign::POS, -144, MType({0x1cb619369e1c641f, 0xbf179269dc44ab85})},
- {Sign::POS, -144, MType({0x3099a17e0461648c, 0xc29107d328c40080})},
- {Sign::POS, -144, MType({0x56dbb75e4813a12b, 0xc60a7d58411fb3d0})},
- {Sign::POS, -144, MType({0x748c47b1bbe45a07, 0xc983f2f925598236})},
- {Sign::POS, -144, MType({0x986da1064b5913e1, 0xccfd68b5d5732873})},
- {Sign::POS, -144, MType({0xfaf478d3d0b31300, 0xd076de8e516e6348})},
- {Sign::POS, -144, MType({0xfe47f0b26ba754ff, 0xd3f05482994cef77})},
- {Sign::POS, -144, MType({0x2e419b90d8e709b7, 0xd769ca92ad1089c2})},
- {Sign::POS, -144, MType({0x406d82eaca788b6f, 0xdae340be8cbaeee9})},
- {Sign::POS, -144, MType({0x140a2bff40e0d670, 0xde5cb706384ddbaf})},
- {Sign::POS, -144, MType({0xb2089d06e51d8034, 0xe1d62d69afcb0cd5})},
- {Sign::POS, -144, MType({0x4d0c626a636f2e4f, 0xe54fa3e8f3343f1f})},
- {Sign::POS, -144, MType({0x416b93f8c6f48d30, 0xe8c91a84028b2f4e})},
- {Sign::POS, -144, MType({0x152eda1dd615c6f5, 0xec42913addd19a25})},
- {Sign::POS, -144, MType({0x781173186fc07a66, 0xefbc080d85093c66})},
- {Sign::POS, -144, MType({0x43813830e974324d, 0xf3357efbf833d2d5})},
- {Sign::POS, -144, MType({0x7a9ea2ef6e1f5d41, 0xf6aef60637531a34})},
- {Sign::POS, -144, MType({0x4a3cd2525dccc623, 0xfa286d2c4268cf47})},
- {Sign::POS, -144, MType({0x8e19004ae218d5d, 0xfda1e46e1976aed1})},
- {Sign::POS, -143, MType({0x9b62aaca25d5d18a, 0x808dade5de3f3aca})},
- {Sign::POS, -143, MType({0xbee9a8d43e00613c, 0x824a69a295c0f02b})},
- {Sign::POS, -143, MType({0xd8d4b69c2056f729, 0x8407256d334155ed})},
- {Sign::POS, -143, MType({0xe7cc28605d7bb77e, 0x85c3e145b6c14a72})},
- {Sign::POS, -143, MType({0xff51b4bdc834a8f1, 0x87809d2c2041ac1c})},
- {Sign::POS, -143, MType({0x47c0774aa81c3561, 0x893d59206fc3594e})},
- {Sign::POS, -143, MType({0xfe4cf331ecb9eb62, 0x8afa1522a5473068})},
+ {Sign::NEG, -143, 0x8af8b9b3'22ba8c7d'54d7e498'98ca0093_u128},
+ {Sign::NEG, -143, 0x893c0652'9deffc3d'c321bbf1'6665f29c_u128},
+ {Sign::NEG, -143, 0x877f52e4'33ac7ec4'8246df71'40c3e4ae_u128},
+ {Sign::NEG, -143, 0x85c29f67'e3ef35bc'1deaa9e8'5780e4c1_u128},
+ {Sign::NEG, -143, 0x8405ebdd'aeb742cf'0cd8a512'1a9162d0_u128},
+ {Sign::NEG, -143, 0x82493845'9403c7a7'b10486fa'4644308d_u128},
+ {Sign::NEG, -143, 0x808c849f'93d3e5f0'578a2f61'eedd4be8_u128},
+ {Sign::NEG, -144, 0xfd9fa1d7'5c4d7ea6'715b4a49'1790e8a7_u128},
+ {Sign::NEG, -144, 0xfa263a53'c5f6eaf4'efb6273a'04c71573_u128},
+ {Sign::NEG, -144, 0xf6acd2b4'64a25420'474d9015'60c17807_u128},
+ {Sign::NEG, -144, 0xf3336af9'384dfd7c'6b9a5dec'eb80ec57_u128},
+ {Sign::NEG, -144, 0xefba0322'40f82a5d'2665a32f'7cc64f79_u128},
+ {Sign::NEG, -144, 0xec409b2f'7e9f1e16'17c8a673'16659363_u128},
+ {Sign::NEG, -144, 0xe8c73320'f1411bfa'b62cdd3e'f5c8673d_u128},
+ {Sign::NEG, -144, 0xe54dcaf6'98dc675e'4e4be6d5'a4a07422_u128},
+ {Sign::NEG, -144, 0xe1d462b0'756f4394'032f86ff'08c92e22_u128},
+ {Sign::NEG, -144, 0xde5afa4e'86f7f3ee'ce31a0d2'7359396f_u128},
+ {Sign::NEG, -144, 0xdae191d0'cd74bbc1'7efc3180'aee36373_u128},
+ {Sign::NEG, -144, 0xd7682937'48e3de5e'bb894b1e'0ce72fc4_u128},
+ {Sign::NEG, -144, 0xd3eec081'f9439f19'00230f6c'7270f8be_u128},
+ {Sign::NEG, -144, 0xd07557b0'de924142'9f63aaa5'63e9a399_u128},
+ {Sign::NEG, -144, 0xccfbeec3'f8ce082d'c2354e44'1015e7eb_u128},
+ {Sign::NEG, -144, 0xc98285bb'47f5372c'67d22bcf'5a452a4c_u128},
+ {Sign::NEG, -144, 0xc6091c96'cc061190'65c46fa3'e3afea18_u128},
+ {Sign::NEG, -144, 0xc28fb356'84fedaab'67e63bbe'1405c20d_u128},
+ {Sign::NEG, -144, 0xbf1649fa'72ddd5ce'f061a284'212afbad_u128},
+ {Sign::NEG, -144, 0xbb9ce082'95a1464c'57b0a190'1625b539_u128},
+ {Sign::NEG, -144, 0xb82376ee'ed476f74'cc9d1c79'd93a9a1e_u128},
+ {Sign::NEG, -144, 0xb4aa0d3f'79ce9499'5440d7a1'31392da8_u128},
+ {Sign::NEG, -144, 0xb130a374'3b34f90a'ca0572f7'c9f7a7de_u128},
+ {Sign::NEG, -144, 0xadb7398d'3178e019'dfa464cb'37fe6455_u128},
+ {Sign::NEG, -144, 0xaa3dcf8a'5c988d17'1d26f48e'fb62e2e0_u128},
+ {Sign::NEG, -144, 0xa6c4656b'bc924352'e0e635a6'81d259e2_u128},
+ {Sign::NEG, -144, 0xa34afb31'5164461d'5f8b022f'27cbda35_u128},
+ {Sign::NEG, -144, 0x9fd190db'1b0cd8c6'a40df5ca'390a0465_u128},
+ {Sign::NEG, -144, 0x9c582669'198a3e9e'8fb76866'f01c4f2d_u128},
+ {Sign::NEG, -144, 0x98debbdb'4cdabaf4'da1f690c'752fdeff_u128},
+ {Sign::NEG, -144, 0x95655131'b4fc9119'112db8a3'dc07ee78_u128},
+ {Sign::NEG, -144, 0x91ebe66c'51ee045a'9919c4c2'2125c79e_u128},
+ {Sign::NEG, -144, 0x8e727b8b'23ad5808'ac6aa272'26204db3_u128},
+ {Sign::NEG, -144, 0x8af9108e'2a38cf72'5bf708fe'ad2b1780_u128},
+ {Sign::NEG, -144, 0x877fa575'658eade6'8ee54cbc'53cd19ed_u128},
+ {Sign::NEG, -144, 0x84063a40'd5ad36b4'02ab59d3'8cc6e2c5_u128},
+ {Sign::NEG, -144, 0x808ccef0'7a92ad29'4b0eaf0a'99286378_u128},
+ {Sign::NEG, -145, 0xfa26c708'a87aa929'a448b11f'012c975c_u128},
+ {Sign::NEG, -145, 0xf333eff8'c556e089'b0a1d584'117de73b_u128},
+ {Sign::NEG, -145, 0xec4118b1'4bb6870e'e890f9fb'57fdabb6_u128},
+ {Sign::NEG, -145, 0xe54e4132'3b962355'261d48c7'1e693130_u128},
+ {Sign::NEG, -145, 0xde5b697b'94f23bf7'efecdd48'ed894c32_u128},
+ {Sign::NEG, -145, 0xd768918d'57c75792'7944b995'7598a88a_u128},
+ {Sign::NEG, -145, 0xd075b967'8411fcbf'a208bc08'75093645_u128},
+ {Sign::NEG, -145, 0xc982e10a'19ceb219'f6bb94d8'9da8b432_u128},
+ {Sign::NEG, -145, 0xc2900875'18f9fe3b'b07ebbab'782457b0_u128},
+ {Sign::NEG, -145, 0xbb9d2fa8'819067be'b5126529'45eb9165_u128},
+ {Sign::NEG, -145, 0xb4aa56a4'538e753c'96d57890'e171eea5_u128},
+ {Sign::NEG, -145, 0xadb77d68'8ef0ad4e'94c5854b'9cd01726_u128},
+ {Sign::NEG, -145, 0xa6c4a3f5'33b3968d'9a7eb881'1ec3e6bb_u128},
+ {Sign::NEG, -145, 0x9fd1ca4a'41d3b792'403bd2ab'3e0fa2d7_u128},
+ {Sign::NEG, -145, 0x98def067'b94d96f4'cad61d29'db384b6b_u128},
+ {Sign::NEG, -145, 0x91ec164d'9a1dbb4d'2bc55fd6'b8a306ec_u128},
+ {Sign::NEG, -145, 0x8af93bfb'e440ab33'011fd699'5111a927_u128},
+ {Sign::NEG, -145, 0x84066172'97b2ed3d'959a26fa'ac7e5494_u128},
+ {Sign::NEG, -146, 0xfa270d63'68e21007'c10eab72'66ac6bc0_u128},
+ {Sign::NEG, -146, 0xec415772'74ef0439'0bb178b9'0026b2b2_u128},
+ {Sign::NEG, -146, 0xde5ba112'5385c43b'ac3bfd92'5e6b33e1_u128},
+ {Sign::NEG, -146, 0xd075ea43'049f5d3b'9d0a01a9'5b355319_u128},
+ {Sign::NEG, -146, 0xc2903304'8834dc64'31b3b7b2'0a6a6496_u128},
+ {Sign::NEG, -146, 0xb4aa7b56'de3f4ee0'170da891'504620f4_u128},
+ {Sign::NEG, -146, 0xa6c4c33a'06b7c1d9'53289e84'744549cb_u128},
+ {Sign::NEG, -146, 0x98df0aae'01974279'45519048'b0ce7e7f_u128},
+ {Sign::NEG, -146, 0x8af951b2'ced6dde8'a6118c42'bf99407e_u128},
+ {Sign::NEG, -147, 0xfa273090'dcdf429f'0e5b474c'c5a64cf6_u128},
+ {Sign::NEG, -147, 0xde5bbcdd'c0b533aa'a74dab3b'd6067bc7_u128},
+ {Sign::NEG, -147, 0xc290484c'4921a941'9f73f4e3'7357341b_u128},
+ {Sign::NEG, -147, 0xa6c4d2dc'7616bdb0'31bf5d5f'815220e7_u128},
+ {Sign::NEG, -147, 0x8af95c8e'47868b41'4b987ca5'fca242d7_u128},
+ {Sign::NEG, -148, 0xde5bcac3'7ac6587d'19be3fab'd93832c5_u128},
+ {Sign::NEG, -148, 0xa6c4daad'af3d75e0'8fd43f0c'9ce444d3_u128},
+ {Sign::NEG, -149, 0xde5bd1b6'58ad4676'061cd853'e796bc2c_u128},
+ {Sign::NEG, -150, 0xde5bd52f'c7d8545f'87d6afab'fba0644f_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -150, 0xde5bdc22'a69d9e19'a9bf3200'1043629d_u128},
+ {Sign::POS, -149, 0xde5bdf9c'1637d9ef'8014f0f3'60272d82_u128},
+ {Sign::POS, -148, 0xa6c4ea50'24795bd2'fe94a02f'c639c0e3_u128},
+ {Sign::POS, -148, 0xde5be68e'f5db7f99'bee710a5'ace7c8d4_u128},
+ {Sign::POS, -147, 0x8af97245'3faf11e8'1a778d81'00437e4f_u128},
+ {Sign::POS, -147, 0xa6c4f221'608e89fe'97d773f8'992f7051_u128},
+ {Sign::POS, -147, 0xc29072db'dd9a0dd5'0c9ee584'1a3afa95_u128},
+ {Sign::POS, -147, 0xde5bf474'b6df8331'7b644b13'993cf4ef_u128},
+ {Sign::POS, -147, 0xfa2776eb'ec6ccfdb'3448f66e'2bd7a0ca_u128},
+ {Sign::POS, -146, 0x8af97d20'bf27eccd'6a7ca5f1'a87a1a3c_u128},
+ {Sign::POS, -146, 0x98df3f3a'b64b431d'245675fe'3061108f_u128},
+ {Sign::POS, -146, 0xa6c501c3'dba75dc2'64136e97'019d0a3b_u128},
+ {Sign::POS, -146, 0xb4aac4bc'2f432fa3'6cdadac4'd6925bd4_u128},
+ {Sign::POS, -146, 0xc2908823'b125aba7'2899e237'91d29632_u128},
+ {Sign::POS, -146, 0xd0764bfa'6155c4b5'28039e1f'0323a4c1_u128},
+ {Sign::POS, -146, 0xde5c1040'3fda6db5'a2912e03'afc8cc28_u128},
+ {Sign::POS, -146, 0xec41d4f5'4cba9991'7681cc9f'9e0d89f9_u128},
+ {Sign::POS, -146, 0xfa279a19'87fd3b32'28dae4b7'241255e1_u128},
+ {Sign::POS, -145, 0x8406afd6'78d4a2c0'f2b412f8'dceda28e_u128},
+ {Sign::POS, -145, 0x8af992d7'c4e2d5b5'bf5dccd9'67504857_u128},
+ {Sign::POS, -145, 0x91ec7610'a82cafed'3716dbf9'50b07f85_u128},
+ {Sign::POS, -145, 0x98df5981'22b5aadd'69eebe0b'8e5b18e1_u128},
+ {Sign::POS, -145, 0x9fd23d29'34813ffc'bb583ce6'5af56beb_u128},
+ {Sign::POS, -145, 0xa6c52108'dd92e8c1'e22978ef'a7a962a0_u128},
+ {Sign::POS, -145, 0xadb80520'1dee1ea3'e89bf389'8ef27836_u128},
+ {Sign::POS, -145, 0xb4aae96e'f5965b1a'2c4c997e'c90bab0b_u128},
+ {Sign::POS, -145, 0xbb9dcdf5'648f179c'5e3bcd6f'21fe6224_u128},
+ {Sign::POS, -145, 0xc290b2b3'6adbcda2'82cd723b'f1524680_u128},
+ {Sign::POS, -145, 0xc98397a9'087ff6a4'f1c8f574'935e109b_u128},
+ {Sign::POS, -145, 0xd0767cd6'3d7f0c1c'565959c2'e4394a59_u128},
+ {Sign::POS, -145, 0xd769623b'09dc8781'af0d4157'bc4f05be_u128},
+ {Sign::POS, -145, 0xde5c47d7'6d9be24e'4dd6f857'6e9188b8_u128},
+ {Sign::POS, -145, 0xe54f2dab'68c095fb'd80c7f46'484eee3d_u128},
+ {Sign::POS, -145, 0xec4213b6'fb4e1c04'46679575'12a6bd26_u128},
+ {Sign::POS, -145, 0xf334f9fa'2547ede1'e505c36d'95a074fa_u128},
+ {Sign::POS, -145, 0xfa27e074'e6b1850f'5368655f'1ce3110b_u128},
+ {Sign::POS, -144, 0x808d6393'9fc72d83'c23a5ac5'7f06c112_u128},
+ {Sign::POS, -144, 0x8406d708'97f0f4a2'df39eb58'90580f93_u128},
+ {Sign::POS, -144, 0x87804a99'5bd7d4a2'cd896f3e'43f38669_u128},
+ {Sign::POS, -144, 0x8af9be45'eb7d8a41'83b16ff7'eecace8c_u128},
+ {Sign::POS, -144, 0x8e73320e'46e3d23d'21ec7ae8'ffa1531d_u128},
+ {Sign::POS, -144, 0x91eca5f2'6e0c6953'f227268d'464ae907_u128},
+ {Sign::POS, -144, 0x956619f2'60f90c44'680017af'3bbaf2d3_u128},
+ {Sign::POS, -144, 0x98df8e0e'1fab77cd'20c8069e'4ae400de_u128},
+ {Sign::POS, -144, 0x9c590245'aa2568ac'e381c465'1a67ee13_u128},
+ {Sign::POS, -144, 0x9fd27699'00689ba2'a0e23fff'd718794e_u128},
+ {Sign::POS, -144, 0xa34beb08'2276cd6d'73508b92'7f485b97_u128},
+ {Sign::POS, -144, 0xa6c55f93'1051bacc'9ee5e19f'2eecdb55_u128},
+ {Sign::POS, -144, 0xaa3ed439'c9fb207f'916daa3c'6c8fdc9d_u128},
+ {Sign::POS, -144, 0xadb848fc'4f74bb45'e265804b'77126ed3_u128},
+ {Sign::POS, -144, 0xb131bdda'a0c047df'52fd36ae'943fd7b4_u128},
+ {Sign::POS, -144, 0xb4ab32d4'bddf830b'ce16dd7f'60311bf6_u128},
+ {Sign::POS, -144, 0xb824a7ea'a6d4298b'6846c745'1d8105ac_u128},
+ {Sign::POS, -144, 0xbb9e1d1c'5b9ff81e'5fd38e2b'0650a884_u128},
+ {Sign::POS, -144, 0xbf179269'dc44ab85'1cb61936'9e1c641f_u128},
+ {Sign::POS, -144, 0xc29107d3'28c40080'3099a17e'0461648c_u128},
+ {Sign::POS, -144, 0xc60a7d58'411fb3d0'56dbb75e'4813a12b_u128},
+ {Sign::POS, -144, 0xc983f2f9'25598236'748c47b1'bbe45a07_u128},
+ {Sign::POS, -144, 0xccfd68b5'd5732873'986da106'4b5913e1_u128},
+ {Sign::POS, -144, 0xd076de8e'516e6348'faf478d3'd0b31300_u128},
+ {Sign::POS, -144, 0xd3f05482'994cef77'fe47f0b2'6ba754ff_u128},
+ {Sign::POS, -144, 0xd769ca92'ad1089c2'2e419b90'd8e709b7_u128},
+ {Sign::POS, -144, 0xdae340be'8cbaeee9'406d82ea'ca788b6f_u128},
+ {Sign::POS, -144, 0xde5cb706'384ddbaf'140a2bff'40e0d670_u128},
+ {Sign::POS, -144, 0xe1d62d69'afcb0cd5'b2089d06'e51d8034_u128},
+ {Sign::POS, -144, 0xe54fa3e8'f3343f1f'4d0c626a'636f2e4f_u128},
+ {Sign::POS, -144, 0xe8c91a84'028b2f4e'416b93f8'c6f48d30_u128},
+ {Sign::POS, -144, 0xec42913a'ddd19a25'152eda1d'd615c6f5_u128},
+ {Sign::POS, -144, 0xefbc080d'85093c66'78117318'6fc07a66_u128},
+ {Sign::POS, -144, 0xf3357efb'f833d2d5'43813830'e974324d_u128},
+ {Sign::POS, -144, 0xf6aef606'37531a34'7a9ea2ef'6e1f5d41_u128},
+ {Sign::POS, -144, 0xfa286d2c'4268cf47'4a3cd252'5dccc623_u128},
+ {Sign::POS, -144, 0xfda1e46e'1976aed1'08e19004'ae218d5d_u128},
+ {Sign::POS, -143, 0x808dade5'de3f3aca'9b62aaca'25d5d18a_u128},
+ {Sign::POS, -143, 0x824a69a2'95c0f02b'bee9a8d4'3e00613c_u128},
+ {Sign::POS, -143, 0x8407256d'334155ed'd8d4b69c'2056f729_u128},
+ {Sign::POS, -143, 0x85c3e145'b6c14a72'e7cc2860'5d7bb77e_u128},
+ {Sign::POS, -143, 0x87809d2c'2041ac1c'ff51b4bd'c834a8f1_u128},
+ {Sign::POS, -143, 0x893d5920'6fc3594e'47c0774a'a81c3561_u128},
+ {Sign::POS, -143, 0x8afa1522'a5473068'fe4cf331'ecb9eb62_u128},
},
// -log10(r) for the fourth step, generated by SageMath with:
//
// for i in range(-65, 65):
// r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) );
// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent();
- // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",",
+ // format_hex(m), "},");
/* .step_4 = */
{
- {Sign::NEG, -151, MType({0xe471a82bbedbe0ae, 0xe1d5464122cf95a4})},
- {Sign::NEG, -151, MType({0xaf6e93be8e4c1764, 0xde5bd6ec7f7bc110})},
- {Sign::NEG, -151, MType({0xe44848f0a5779499, 0xdae26797a490f80e})},
- {Sign::NEG, -151, MType({0x90205533f4e70566, 0xd768f842920f3a98})},
- {Sign::NEG, -151, MType({0xc01844ace3729e48, 0xd3ef88ed47f688a6})},
- {Sign::NEG, -151, MType({0x8151a2324e41c7c4, 0xd0761997c646e232})},
- {Sign::NEG, -151, MType({0xe0edf74d88cacafd, 0xccfcaa420d004734})},
- {Sign::NEG, -151, MType({0xec0ecc3a5cd27e58, 0xc9833aec1c22b7a6})},
- {Sign::NEG, -151, MType({0xafd5a7e70a6bf214, 0xc609cb95f3ae3381})},
- {Sign::NEG, -151, MType({0x39640ff447f81ceb, 0xc2905c3f93a2babe})},
- {Sign::NEG, -151, MType({0x95db88b5422588b1, 0xbf16ece8fc004d55})},
- {Sign::NEG, -151, MType({0xd25d952f9beffeec, 0xbb9d7d922cc6eb40})},
- {Sign::NEG, -151, MType({0xfc0bb71b6ea03578, 0xb8240e3b25f69478})},
- {Sign::NEG, -151, MType({0x20076ee349cb7b20, 0xb4aa9ee3e78f48f7})},
- {Sign::NEG, -151, MType({0x4b723ba43353643d, 0xb1312f8c719108b4})},
- {Sign::NEG, -151, MType({0x8b6d9b2da7657754, 0xadb7c034c3fbd3a9})},
- {Sign::NEG, -151, MType({0xed1b0a01987ad9b4, 0xaa3e50dcdecfa9cf})},
- {Sign::NEG, -151, MType({0x7d9c03546f57fc11, 0xa6c4e184c20c8b20})},
- {Sign::NEG, -151, MType({0x4a12010d0b0c4727, 0xa34b722c6db27794})},
- {Sign::NEG, -151, MType({0x5f9e7bc4c0f1c851, 0x9fd202d3e1c16f24})},
- {Sign::NEG, -151, MType({0xcb62eac75cacde29, 0x9c58937b1e3971c9})},
- {Sign::NEG, -151, MType({0x9a80c413202be52a, 0x98df2422231a7f7d})},
- {Sign::NEG, -151, MType({0xda197c58c3a6e445, 0x9565b4c8f0649838})},
- {Sign::NEG, -151, MType({0x974e86fb759f3988, 0x91ec456f8617bbf4})},
- {Sign::NEG, -151, MType({0xdf415610dadf46b3, 0x8e72d615e433eaa9})},
- {Sign::NEG, -151, MType({0xbf135a610e7a1ddc, 0x8af966bc0ab92451})},
- {Sign::NEG, -151, MType({0x43e60366a1cb2e09, 0x877ff761f9a768e5})},
- {Sign::NEG, -151, MType({0x7adabf4e9c75efce, 0x84068807b0feb85d})},
- {Sign::NEG, -151, MType({0x7112faf87c6591ee, 0x808d18ad30bf12b3})},
- {Sign::NEG, -152, MType({0x676043ec6b994be5, 0xfa2752a4f1d0efc0})},
- {Sign::NEG, -152, MType({0x9fa73d186649999d, 0xf33473ef12f5cfb9})},
- {Sign::NEG, -152, MType({0xa53db362aa5cc6f0, 0xec419538c4ecc544})},
- {Sign::NEG, -152, MType({0x9266761de5e05f13, 0xe54eb68207b5d053})},
- {Sign::NEG, -152, MType({0x81645201b36e17ba, 0xde5bd7cadb50f0d8})},
- {Sign::NEG, -152, MType({0x8c7a112a9a2b2a52, 0xd768f9133fbe26c5})},
- {Sign::NEG, -152, MType({0xcdea7b1a0dc7ad42, 0xd0761a5b34fd720c})},
- {Sign::NEG, -152, MType({0x5ff854b66e7ded1f, 0xc9833ba2bb0ed2a0})},
- {Sign::NEG, -152, MType({0x5ce6604b0911c5ed, 0xc2905ce9d1f24872})},
- {Sign::NEG, -152, MType({0xdef75d8816cffc59, 0xbb9d7e3079a7d374})},
- {Sign::NEG, -152, MType({0x6e0982bd8d96ef, 0xb4aa9f76b22f739a})},
- {Sign::NEG, -152, MType({0xdb8d1eb50fa7375c, 0xadb7c0bc7b8928d3})},
- {Sign::NEG, -152, MType({0x8a9754fe0c0073a7, 0xa6c4e201d5b4f314})},
- {Sign::NEG, -152, MType({0x27cf61a19e032f69, 0x9fd20346c0b2d24e})},
- {Sign::NEG, -152, MType({0xcd77f7489d9ef50b, 0x98df248b3c82c672})},
- {Sign::NEG, -152, MType({0x95d3c600cf484f03, 0x91ec45cf4924cf74})},
- {Sign::NEG, -152, MType({0x9b257b3ce3f82109, 0x8af96712e698ed45})},
- {Sign::NEG, -152, MType({0xf7afc1d4792b015a, 0x8406885614df1fd7})},
- {Sign::NEG, -153, MType({0x8b6a840831c123d8, 0xfa275331a7eece3b})},
- {Sign::NEG, -153, MType({0x3ef142da7335b35a, 0xec4195b647c38612})},
- {Sign::NEG, -153, MType({0x3e79062c7cbb3b7d, 0xde5bd83a093c6718})},
- {Sign::NEG, -153, MType({0xbe870ed4ed5b755b, 0xd0761abcec597131})},
- {Sign::NEG, -153, MType({0xf3a098743d20fb64, 0xc2905d3ef11aa442})},
- {Sign::NEG, -153, MType({0x124ad974bd15fbca, 0xb4aa9fc017800030})},
- {Sign::NEG, -153, MType({0x4f0b030a9742eb00, 0xa6c4e2405f8984dd})},
- {Sign::NEG, -153, MType({0xde664133cead362d, 0x98df24bfc937322e})},
- {Sign::NEG, -153, MType({0xf4e1bab83f55f5a1, 0x8af9673e54890808})},
- {Sign::NEG, -154, MType({0x8e0522533c713e98, 0xfa27537802fe0c9f})},
- {Sign::NEG, -154, MType({0x129bc1c6f293726e, 0xde5bd871a03259cf})},
- {Sign::NEG, -154, MType({0xe09182166eeb17eb, 0xc2905d6980aef768})},
- {Sign::NEG, -154, MType({0x60f08720313daa3f, 0xa6c4e25fa473e535})},
- {Sign::NEG, -154, MType({0xfcc2ea566b3af38b, 0x8af967540b8122fc})},
- {Sign::NEG, -155, MType({0x3a25757e00f4e3a0, 0xde5bd88d6bad6110})},
- {Sign::NEG, -155, MType({0x55d3f9e70cf177b8, 0xa6c4e26f46e91b3e})},
- {Sign::NEG, -156, MType({0x3d4aac85125398d0, 0xde5bd89b516ae82a})},
- {Sign::NEG, -157, MType({0x9ab5a849a06f400d, 0xde5bd8a24449ac95})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -157, MType({0xd3cc88fd4ef34c2, 0xde5bd8b02a073729})},
- {Sign::POS, -156, MType({0x225916c2b3f33c90, 0xde5bd8b71ce5fd51})},
- {Sign::POS, -155, MType({0x17847f98acf08d54, 0xa6c4e28e8bd3930a})},
- {Sign::POS, -155, MType({0x44397830931fddd, 0xde5bd8c502a38b5e})},
- {Sign::POS, -154, MType({0xc2ab385913176984, 0x8af9677f79717409})},
- {Sign::POS, -154, MType({0xe454dec82bde52e5, 0xa6c4e29e2e48d4cc})},
- {Sign::POS, -154, MType({0xfe1522b0470d7d7f, 0xc2905dbe9fd7e82f})},
- {Sign::POS, -154, MType({0xa6e2721f2afc3cce, 0xde5bd8e0ce1eae6a})},
- {Sign::POS, -154, MType({0x75b3458eec3c106c, 0xfa275404b91d27b4})},
- {Sign::POS, -153, MType({0x80bf0ff2f6cd9f93, 0x8af967953069aa22})},
- {Sign::POS, -153, MType({0xf09cc73b7013b906, 0x98df2528e2a09a29})},
- {Sign::POS, -153, MType({0x55ee1480619827c4, 0xa6c4e2bd7333640c})},
- {Sign::POS, -153, MType({0x7c2e48d772250b3c, 0xb4aaa052e22207e5})},
- {Sign::POS, -153, MType({0x2ed8ba8c6fa81c98, 0xc2905de92f6c85d1})},
- {Sign::POS, -153, MType({0x3968c5214f33fc4f, 0xd0761b805b12ddeb})},
- {Sign::POS, -153, MType({0x6759c94e2d017fad, 0xde5bd9186515104f})},
- {Sign::POS, -153, MType({0x84272d014c70fe58, 0xec4196b14d731d19})},
- {Sign::POS, -153, MType({0x5b4c5b5f180b9fe1, 0xfa27544b142d0465})},
- {Sign::POS, -152, MType({0x5c22626110c254a4, 0x840688f2dca16327})},
- {Sign::POS, -152, MType({0xb345ef5d90dd6545, 0x8af967c09e5a3178})},
- {Sign::POS, -152, MType({0x98ce92087c5cb614, 0x91ec468ecf40ed34})},
- {Sign::POS, -152, MType({0xf27a0a6056dcfe57, 0x98df255d6f559668})},
- {Sign::POS, -152, MType({0xa6061afeb7929f24, 0x9fd2042c7e982d23})},
- {Sign::POS, -152, MType({0x99308918494a4a20, 0xa6c4e2fbfd08b172})},
- {Sign::POS, -152, MType({0xb1b71c7cca69a844, 0xadb7c1cbeaa72363})},
- {Sign::POS, -152, MType({0xd5579f970cf000a9, 0xb4aaa09c47738304})},
- {Sign::POS, -152, MType({0xe9cfdf6cf676df42, 0xbb9d7f6d136dd063})},
- {Sign::POS, -152, MType({0xd4ddab9f8032bbab, 0xc2905e3e4e960b8e})},
- {Sign::POS, -152, MType({0x7c3ed66ab6f39fe9, 0xc9833d0ff8ec3493})},
- {Sign::POS, -152, MType({0xc5b134a5bb25cf2e, 0xd0761be212704b7f})},
- {Sign::POS, -152, MType({0x96f29dc2c0d26ca0, 0xd768fab49b225061})},
- {Sign::POS, -152, MType({0xd5c0ebcf0fa0221e, 0xde5bd98793024346})},
- {Sign::POS, -152, MType({0x67d9fb7302d3c705, 0xe54eb85afa10243d})},
- {Sign::POS, -152, MType({0x32fbabf2095106f1, 0xec41972ed04bf353})},
- {Sign::POS, -152, MType({0x1ce3df2aa59b0889, 0xf334760315b5b096})},
- {Sign::POS, -152, MType({0xb5079966dd5143e, 0xfa2754d7ca4d5c14})},
- {Sign::POS, -151, MType({0x71ffb12505e19d89, 0x808d19d677097aed})},
- {Sign::POS, -151, MType({0x4657417a9e657eae, 0x8406894140833efc})},
- {Sign::POS, -151, MType({0x758de3f168f9f8c9, 0x877ff8ac4193fa3d})},
- {Sign::POS, -151, MType({0xf2828ffc57f43581, 0x8af968177a3bacb7})},
- {Sign::POS, -151, MType({0xb0143e5be77b1053, 0x8e72d782ea7a5672})},
- {Sign::POS, -151, MType({0xa121e91e1d8769ef, 0x91ec46ee924ff774})},
- {Sign::POS, -151, MType({0xb88a8b9e89e47b9c, 0x9565b65a71bc8fc4})},
- {Sign::POS, -151, MType({0xe92d228646302a9c, 0x98df25c688c01f69})},
- {Sign::POS, -151, MType({0x25e8abcbf5db5b8c, 0x9c589532d75aa66b})},
- {Sign::POS, -151, MType({0x619c26b3c62a45c8, 0x9fd2049f5d8c24cf})},
- {Sign::POS, -151, MType({0x8f2693cf6e34c6cc, 0xa34b740c1b549a9d})},
- {Sign::POS, -151, MType({0xa166f4fe2ee6b59a, 0xa6c4e37910b407dc})},
- {Sign::POS, -151, MType({0x8b3c4d6cd3003616, 0xaa3e52e63daa6c93})},
- {Sign::POS, -151, MType({0x3f85a195af160c71, 0xadb7c253a237c8c9})},
- {Sign::POS, -151, MType({0xb121f740a191f084, 0xb13131c13e5c1c84})},
- {Sign::POS, -151, MType({0xd2f0558312b2e136, 0xb4aaa12f121767cc})},
- {Sign::POS, -151, MType({0x97cfc4bff48d77de, 0xb824109d1d69aaa8})},
- {Sign::POS, -151, MType({0xf29f4ea7c30c3ba5, 0xbb9d800b6052e51e})},
- {Sign::POS, -151, MType({0xd63dfe3883eff4e9, 0xbf16ef79dad31736})},
- {Sign::POS, -151, MType({0x358adfbdc6d0009f, 0xc2905ee88cea40f7})},
- {Sign::POS, -151, MType({0x36500d0a51aa3b6, 0xc609ce5776986267})},
- {Sign::POS, -151, MType({0x32ab7057c2155e78, 0xc9833dc697dd7b8d})},
- {Sign::POS, -151, MType({0xb63d3e874add3ff0, 0xccfcad35f0b98c70})},
- {Sign::POS, -151, MType({0x80f97ce0f6673948, 0xd0761ca5812c9518})},
- {Sign::POS, -151, MType({0x85bf3e340580712d, 0xd3ef8c154936958b})},
- {Sign::POS, -151, MType({0xb76d969d42ce9734, 0xd768fb8548d78dd0})},
- {Sign::POS, -151, MType({0x8e39b8702d0373a, 0xdae26af5800f7def})},
- {Sign::POS, -151, MType({0x6d0063a923dd0cc6, 0xde5bda65eede65ed})},
+ {Sign::NEG, -151, 0xe1d54641'22cf95a4'e471a82b'bedbe0ae_u128},
+ {Sign::NEG, -151, 0xde5bd6ec'7f7bc110'af6e93be'8e4c1764_u128},
+ {Sign::NEG, -151, 0xdae26797'a490f80e'e44848f0'a5779499_u128},
+ {Sign::NEG, -151, 0xd768f842'920f3a98'90205533'f4e70566_u128},
+ {Sign::NEG, -151, 0xd3ef88ed'47f688a6'c01844ac'e3729e48_u128},
+ {Sign::NEG, -151, 0xd0761997'c646e232'8151a232'4e41c7c4_u128},
+ {Sign::NEG, -151, 0xccfcaa42'0d004734'e0edf74d'88cacafd_u128},
+ {Sign::NEG, -151, 0xc9833aec'1c22b7a6'ec0ecc3a'5cd27e58_u128},
+ {Sign::NEG, -151, 0xc609cb95'f3ae3381'afd5a7e7'0a6bf214_u128},
+ {Sign::NEG, -151, 0xc2905c3f'93a2babe'39640ff4'47f81ceb_u128},
+ {Sign::NEG, -151, 0xbf16ece8'fc004d55'95db88b5'422588b1_u128},
+ {Sign::NEG, -151, 0xbb9d7d92'2cc6eb40'd25d952f'9beffeec_u128},
+ {Sign::NEG, -151, 0xb8240e3b'25f69478'fc0bb71b'6ea03578_u128},
+ {Sign::NEG, -151, 0xb4aa9ee3'e78f48f7'20076ee3'49cb7b20_u128},
+ {Sign::NEG, -151, 0xb1312f8c'719108b4'4b723ba4'3353643d_u128},
+ {Sign::NEG, -151, 0xadb7c034'c3fbd3a9'8b6d9b2d'a7657754_u128},
+ {Sign::NEG, -151, 0xaa3e50dc'decfa9cf'ed1b0a01'987ad9b4_u128},
+ {Sign::NEG, -151, 0xa6c4e184'c20c8b20'7d9c0354'6f57fc11_u128},
+ {Sign::NEG, -151, 0xa34b722c'6db27794'4a12010d'0b0c4727_u128},
+ {Sign::NEG, -151, 0x9fd202d3'e1c16f24'5f9e7bc4'c0f1c851_u128},
+ {Sign::NEG, -151, 0x9c58937b'1e3971c9'cb62eac7'5cacde29_u128},
+ {Sign::NEG, -151, 0x98df2422'231a7f7d'9a80c413'202be52a_u128},
+ {Sign::NEG, -151, 0x9565b4c8'f0649838'da197c58'c3a6e445_u128},
+ {Sign::NEG, -151, 0x91ec456f'8617bbf4'974e86fb'759f3988_u128},
+ {Sign::NEG, -151, 0x8e72d615'e433eaa9'df415610'dadf46b3_u128},
+ {Sign::NEG, -151, 0x8af966bc'0ab92451'bf135a61'0e7a1ddc_u128},
+ {Sign::NEG, -151, 0x877ff761'f9a768e5'43e60366'a1cb2e09_u128},
+ {Sign::NEG, -151, 0x84068807'b0feb85d'7adabf4e'9c75efce_u128},
+ {Sign::NEG, -151, 0x808d18ad'30bf12b3'7112faf8'7c6591ee_u128},
+ {Sign::NEG, -152, 0xfa2752a4'f1d0efc0'676043ec'6b994be5_u128},
+ {Sign::NEG, -152, 0xf33473ef'12f5cfb9'9fa73d18'6649999d_u128},
+ {Sign::NEG, -152, 0xec419538'c4ecc544'a53db362'aa5cc6f0_u128},
+ {Sign::NEG, -152, 0xe54eb682'07b5d053'9266761d'e5e05f13_u128},
+ {Sign::NEG, -152, 0xde5bd7ca'db50f0d8'81645201'b36e17ba_u128},
+ {Sign::NEG, -152, 0xd768f913'3fbe26c5'8c7a112a'9a2b2a52_u128},
+ {Sign::NEG, -152, 0xd0761a5b'34fd720c'cdea7b1a'0dc7ad42_u128},
+ {Sign::NEG, -152, 0xc9833ba2'bb0ed2a0'5ff854b6'6e7ded1f_u128},
+ {Sign::NEG, -152, 0xc2905ce9'd1f24872'5ce6604b'0911c5ed_u128},
+ {Sign::NEG, -152, 0xbb9d7e30'79a7d374'def75d88'16cffc59_u128},
+ {Sign::NEG, -152, 0xb4aa9f76'b22f739a'006e0982'bd8d96ef_u128},
+ {Sign::NEG, -152, 0xadb7c0bc'7b8928d3'db8d1eb5'0fa7375c_u128},
+ {Sign::NEG, -152, 0xa6c4e201'd5b4f314'8a9754fe'0c0073a7_u128},
+ {Sign::NEG, -152, 0x9fd20346'c0b2d24e'27cf61a1'9e032f69_u128},
+ {Sign::NEG, -152, 0x98df248b'3c82c672'cd77f748'9d9ef50b_u128},
+ {Sign::NEG, -152, 0x91ec45cf'4924cf74'95d3c600'cf484f03_u128},
+ {Sign::NEG, -152, 0x8af96712'e698ed45'9b257b3c'e3f82109_u128},
+ {Sign::NEG, -152, 0x84068856'14df1fd7'f7afc1d4'792b015a_u128},
+ {Sign::NEG, -153, 0xfa275331'a7eece3b'8b6a8408'31c123d8_u128},
+ {Sign::NEG, -153, 0xec4195b6'47c38612'3ef142da'7335b35a_u128},
+ {Sign::NEG, -153, 0xde5bd83a'093c6718'3e79062c'7cbb3b7d_u128},
+ {Sign::NEG, -153, 0xd0761abc'ec597131'be870ed4'ed5b755b_u128},
+ {Sign::NEG, -153, 0xc2905d3e'f11aa442'f3a09874'3d20fb64_u128},
+ {Sign::NEG, -153, 0xb4aa9fc0'17800030'124ad974'bd15fbca_u128},
+ {Sign::NEG, -153, 0xa6c4e240'5f8984dd'4f0b030a'9742eb00_u128},
+ {Sign::NEG, -153, 0x98df24bf'c937322e'de664133'cead362d_u128},
+ {Sign::NEG, -153, 0x8af9673e'54890808'f4e1bab8'3f55f5a1_u128},
+ {Sign::NEG, -154, 0xfa275378'02fe0c9f'8e052253'3c713e98_u128},
+ {Sign::NEG, -154, 0xde5bd871'a03259cf'129bc1c6'f293726e_u128},
+ {Sign::NEG, -154, 0xc2905d69'80aef768'e0918216'6eeb17eb_u128},
+ {Sign::NEG, -154, 0xa6c4e25f'a473e535'60f08720'313daa3f_u128},
+ {Sign::NEG, -154, 0x8af96754'0b8122fc'fcc2ea56'6b3af38b_u128},
+ {Sign::NEG, -155, 0xde5bd88d'6bad6110'3a25757e'00f4e3a0_u128},
+ {Sign::NEG, -155, 0xa6c4e26f'46e91b3e'55d3f9e7'0cf177b8_u128},
+ {Sign::NEG, -156, 0xde5bd89b'516ae82a'3d4aac85'125398d0_u128},
+ {Sign::NEG, -157, 0xde5bd8a2'4449ac95'9ab5a849'a06f400d_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -157, 0xde5bd8b0'2a073729'0d3cc88f'd4ef34c2_u128},
+ {Sign::POS, -156, 0xde5bd8b7'1ce5fd51'225916c2'b3f33c90_u128},
+ {Sign::POS, -155, 0xa6c4e28e'8bd3930a'17847f98'acf08d54_u128},
+ {Sign::POS, -155, 0xde5bd8c5'02a38b5e'04439783'0931fddd_u128},
+ {Sign::POS, -154, 0x8af9677f'79717409'c2ab3859'13176984_u128},
+ {Sign::POS, -154, 0xa6c4e29e'2e48d4cc'e454dec8'2bde52e5_u128},
+ {Sign::POS, -154, 0xc2905dbe'9fd7e82f'fe1522b0'470d7d7f_u128},
+ {Sign::POS, -154, 0xde5bd8e0'ce1eae6a'a6e2721f'2afc3cce_u128},
+ {Sign::POS, -154, 0xfa275404'b91d27b4'75b3458e'ec3c106c_u128},
+ {Sign::POS, -153, 0x8af96795'3069aa22'80bf0ff2'f6cd9f93_u128},
+ {Sign::POS, -153, 0x98df2528'e2a09a29'f09cc73b'7013b906_u128},
+ {Sign::POS, -153, 0xa6c4e2bd'7333640c'55ee1480'619827c4_u128},
+ {Sign::POS, -153, 0xb4aaa052'e22207e5'7c2e48d7'72250b3c_u128},
+ {Sign::POS, -153, 0xc2905de9'2f6c85d1'2ed8ba8c'6fa81c98_u128},
+ {Sign::POS, -153, 0xd0761b80'5b12ddeb'3968c521'4f33fc4f_u128},
+ {Sign::POS, -153, 0xde5bd918'6515104f'6759c94e'2d017fad_u128},
+ {Sign::POS, -153, 0xec4196b1'4d731d19'84272d01'4c70fe58_u128},
+ {Sign::POS, -153, 0xfa27544b'142d0465'5b4c5b5f'180b9fe1_u128},
+ {Sign::POS, -152, 0x840688f2'dca16327'5c226261'10c254a4_u128},
+ {Sign::POS, -152, 0x8af967c0'9e5a3178'b345ef5d'90dd6545_u128},
+ {Sign::POS, -152, 0x91ec468e'cf40ed34'98ce9208'7c5cb614_u128},
+ {Sign::POS, -152, 0x98df255d'6f559668'f27a0a60'56dcfe57_u128},
+ {Sign::POS, -152, 0x9fd2042c'7e982d23'a6061afe'b7929f24_u128},
+ {Sign::POS, -152, 0xa6c4e2fb'fd08b172'99308918'494a4a20_u128},
+ {Sign::POS, -152, 0xadb7c1cb'eaa72363'b1b71c7c'ca69a844_u128},
+ {Sign::POS, -152, 0xb4aaa09c'47738304'd5579f97'0cf000a9_u128},
+ {Sign::POS, -152, 0xbb9d7f6d'136dd063'e9cfdf6c'f676df42_u128},
+ {Sign::POS, -152, 0xc2905e3e'4e960b8e'd4ddab9f'8032bbab_u128},
+ {Sign::POS, -152, 0xc9833d0f'f8ec3493'7c3ed66a'b6f39fe9_u128},
+ {Sign::POS, -152, 0xd0761be2'12704b7f'c5b134a5'bb25cf2e_u128},
+ {Sign::POS, -152, 0xd768fab4'9b225061'96f29dc2'c0d26ca0_u128},
+ {Sign::POS, -152, 0xde5bd987'93024346'd5c0ebcf'0fa0221e_u128},
+ {Sign::POS, -152, 0xe54eb85a'fa10243d'67d9fb73'02d3c705_u128},
+ {Sign::POS, -152, 0xec41972e'd04bf353'32fbabf2'095106f1_u128},
+ {Sign::POS, -152, 0xf3347603'15b5b096'1ce3df2a'a59b0889_u128},
+ {Sign::POS, -152, 0xfa2754d7'ca4d5c14'0b507996'6dd5143e_u128},
+ {Sign::POS, -151, 0x808d19d6'77097aed'71ffb125'05e19d89_u128},
+ {Sign::POS, -151, 0x84068941'40833efc'4657417a'9e657eae_u128},
+ {Sign::POS, -151, 0x877ff8ac'4193fa3d'758de3f1'68f9f8c9_u128},
+ {Sign::POS, -151, 0x8af96817'7a3bacb7'f2828ffc'57f43581_u128},
+ {Sign::POS, -151, 0x8e72d782'ea7a5672'b0143e5b'e77b1053_u128},
+ {Sign::POS, -151, 0x91ec46ee'924ff774'a121e91e'1d8769ef_u128},
+ {Sign::POS, -151, 0x9565b65a'71bc8fc4'b88a8b9e'89e47b9c_u128},
+ {Sign::POS, -151, 0x98df25c6'88c01f69'e92d2286'46302a9c_u128},
+ {Sign::POS, -151, 0x9c589532'd75aa66b'25e8abcb'f5db5b8c_u128},
+ {Sign::POS, -151, 0x9fd2049f'5d8c24cf'619c26b3'c62a45c8_u128},
+ {Sign::POS, -151, 0xa34b740c'1b549a9d'8f2693cf'6e34c6cc_u128},
+ {Sign::POS, -151, 0xa6c4e379'10b407dc'a166f4fe'2ee6b59a_u128},
+ {Sign::POS, -151, 0xaa3e52e6'3daa6c93'8b3c4d6c'd3003616_u128},
+ {Sign::POS, -151, 0xadb7c253'a237c8c9'3f85a195'af160c71_u128},
+ {Sign::POS, -151, 0xb13131c1'3e5c1c84'b121f740'a191f084_u128},
+ {Sign::POS, -151, 0xb4aaa12f'121767cc'd2f05583'12b2e136_u128},
+ {Sign::POS, -151, 0xb824109d'1d69aaa8'97cfc4bf'f48d77de_u128},
+ {Sign::POS, -151, 0xbb9d800b'6052e51e'f29f4ea7'c30c3ba5_u128},
+ {Sign::POS, -151, 0xbf16ef79'dad31736'd63dfe38'83eff4e9_u128},
+ {Sign::POS, -151, 0xc2905ee8'8cea40f7'358adfbd'c6d0009f_u128},
+ {Sign::POS, -151, 0xc609ce57'76986267'036500d0'a51aa3b6_u128},
+ {Sign::POS, -151, 0xc9833dc6'97dd7b8d'32ab7057'c2155e78_u128},
+ {Sign::POS, -151, 0xccfcad35'f0b98c70'b63d3e87'4add3ff0_u128},
+ {Sign::POS, -151, 0xd0761ca5'812c9518'80f97ce0'f6673948_u128},
+ {Sign::POS, -151, 0xd3ef8c15'4936958b'85bf3e34'0580712d_u128},
+ {Sign::POS, -151, 0xd768fb85'48d78dd0'b76d969d'42ce9734_u128},
+ {Sign::POS, -151, 0xdae26af5'800f7def'08e39b87'02d0373a_u128},
+ {Sign::POS, -151, 0xde5bda65'eede65ed'6d0063a9'23dd0cc6_u128},
}};
// > P = fpminimax(log10(1 + x)/x, 3, [|128...|], [-0x1.0002143p-29 , 0x1p-29]);
// > P;
// > dirtyinfnorm(log10(1 + x)/x - P, [-0x1.0002143p-29 , 0x1p-29]);
// 0x1.64fb8...p-123
-const Float128 BIG_COEFFS[4]{
- {Sign::NEG, -131, MType({0x6903c4ce1582517d, 0xde5bd8a9373f89a7})},
- {Sign::POS, -130, MType({0xb8a21791624e2e8a, 0x943d3b1b7a1af679})},
- {Sign::NEG, -130, MType({0x355baaafabc25990, 0xde5bd8a937287195})},
- {Sign::POS, -129, MType({0x355baaafad33dbd9, 0xde5bd8a937287195})},
+constexpr Float128 BIG_COEFFS[4]{
+ {Sign::NEG, -131, 0xde5bd8a9'373f89a7'6903c4ce'1582517d_u128},
+ {Sign::POS, -130, 0x943d3b1b'7a1af679'b8a21791'624e2e8a_u128},
+ {Sign::NEG, -130, 0xde5bd8a9'37287195'355baaaf'abc25990_u128},
+ {Sign::POS, -129, 0xde5bd8a9'37287195'355baaaf'ad33dbd9_u128},
};
// Reuse the output of the fast pass range reduction.
@@ -733,7 +737,7 @@ double log10_accurate(int e_x, int index, double m_x) {
LLVM_LIBC_FUNCTION(double, log10, (double x)) {
using FPBits_t = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
FPBits_t xbits(x);
uint64_t x_u = xbits.uintval();
diff --git a/src/math/generic/log10f.cpp b/src/math/generic/log10f.cpp
index 0216bb2133f1..1b6979d4414a 100644
--- a/src/math/generic/log10f.cpp
+++ b/src/math/generic/log10f.cpp
@@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
constexpr double LOG10_2 = 0x1.34413509f79ffp-2;
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
uint32_t x_u = xbits.uintval();
diff --git a/src/math/generic/log1p.cpp b/src/math/generic/log1p.cpp
index 0edab70124c9..83bd753cde5d 100644
--- a/src/math/generic/log1p.cpp
+++ b/src/math/generic/log1p.cpp
@@ -14,6 +14,7 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "common_constants.h"
@@ -22,19 +23,24 @@ namespace LIBC_NAMESPACE {
// 128-bit precision dyadic floating point numbers.
using Float128 = typename fputil::DyadicFloat<128>;
-using MType = typename Float128::MantissaType;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
namespace {
// Extra errors from P is from using x^2 to reduce evaluation latency.
constexpr double P_ERR = 0x1.0p-50;
-// log(2) with 128-bit prepcision generated by SageMath with:
-// sage: (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
-// sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})");
-const Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
- MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab}));
+// log(2) with 128-bit precision generated by SageMath with:
+// def format_hex(value):
+// l = hex(value)[2:]
+// n = 8
+// x = [l[i:i + n] for i in range(0, len(l), n)]
+// return "0x" + "'".join(x) + "_u128"
+// (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
+// print(format_hex(m));
+constexpr Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
+ 0xb17217f7'd1cf79ab'c9e3b398'03f2f6af_u128);
// R1[i] = 2^-8 * nearestint( 2^8 / (1 + i * 2^-7) )
constexpr double R1[129] = {
@@ -245,139 +251,137 @@ constexpr double P_COEFFS[6] = {-0x1p-1,
// for i in range(129):
// r = 2^-8 * round( 2^8 / (1 + i*2^(-7)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
-// print("{Sign::POS,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64) %
-// 2^64),
-// "})},");
-const Float128 LOG_R1[129] = {
- {Sign::POS, 0, MType(0)},
- {Sign::POS, -134, MType({0x662d417ced007a46, 0x8080abac46f38946})},
- {Sign::POS, -133, MType({0x91d082dce3ddcd38, 0x8102b2c49ac23a4f})},
- {Sign::POS, -133, MType({0xda5f3cc0b3251dbd, 0xc24929464655f45c})},
- {Sign::POS, -132, MType({0xb9e3aea6c444ef07, 0x820aec4f3a222380})},
- {Sign::POS, -132, MType({0x521016bd904dc968, 0xa33576a16f1f4c64})},
- {Sign::POS, -132, MType({0x27cca0bcc06c2f92, 0xb3e4a796a5dac208})},
- {Sign::POS, -132, MType({0xa9dda17056e45ed5, 0xd5779687d887e0d1})},
- {Sign::POS, -132, MType({0x606d89093278a939, 0xf7518e0035c3dd83})},
- {Sign::POS, -131, MType({0xa7c9859530a45153, 0x8cb9de8a32ab368a})},
- {Sign::POS, -131, MType({0x976d3b5b45f6ca0b, 0x9defad3e8f73217a})},
- {Sign::POS, -131, MType({0x3e858f08597b3a69, 0xa6988ae903f562ed})},
- {Sign::POS, -131, MType({0x6a677b4c8bec22e1, 0xb8069857560707a3})},
- {Sign::POS, -131, MType({0xeaf51f66692844ba, 0xc99af2eaca4c4570})},
- {Sign::POS, -131, MType({0x46bbf837b4d320c6, 0xd273b2058de1bd49})},
- {Sign::POS, -131, MType({0x196ab34ce0bccd12, 0xe442c00de2591b47})},
- {Sign::POS, -131, MType({0x3f4e2e660317d55f, 0xed393b1c22351280})},
- {Sign::POS, -131, MType({0xc17bd40d8d9291ec, 0xff4489cedeab2ca6})},
- {Sign::POS, -130, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
- {Sign::POS, -130, MType({0x88713268840cbcc0, 0x8d515bf11fb94f1c})},
- {Sign::POS, -130, MType({0x65c0da506a088484, 0x968b08643409ceb6})},
- {Sign::POS, -130, MType({0x411a5b944aca8708, 0x9b2fe580ac80b17d})},
- {Sign::POS, -130, MType({0xa9fb6cf0ecb411b7, 0xa489ec199dab06f2})},
- {Sign::POS, -130, MType({0xcad2fb8d48054ae0, 0xa93f2f250dac67d1})},
- {Sign::POS, -130, MType({0x149767e410316d2c, 0xadfa035aa1ed8fdc})},
- {Sign::POS, -130, MType({0x34c7bc3d32750fde, 0xb780945bab55dce4})},
- {Sign::POS, -130, MType({0x8f6ebcfb2016a439, 0xbc4c6c2a226399ef})},
- {Sign::POS, -130, MType({0xaa8b6997a402bf30, 0xc5f57f59c7f46155})},
- {Sign::POS, -130, MType({0x2c507fb7a3d0bf6a, 0xcad2d6e7b80bf914})},
- {Sign::POS, -130, MType({0xd0cb02f33f79c16c, 0xcfb6203844b3209a})},
- {Sign::POS, -130, MType({0x58a98f2ad65bee9b, 0xd98ec2bade71e539})},
- {Sign::POS, -130, MType({0x4d57da945b5d0aaa, 0xde8439c1dec56877})},
- {Sign::POS, -130, MType({0x4e9a750b6b68781d, 0xe37fde37807b84e3})},
- {Sign::POS, -130, MType({0xc524848e3443e040, 0xe881bf932af3dac0})},
- {Sign::POS, -130, MType({0x3b020fa1820c9492, 0xf29877ff38809091})},
- {Sign::POS, -130, MType({0x54d2238f75f969b1, 0xf7ad6f26e7ff2ef7})},
- {Sign::POS, -130, MType({0xca0cdf301431b60f, 0xfcc8e3659d9bcbec})},
- {Sign::POS, -129, MType({0xf5bd0b5b3479d5f4, 0x80f572b1363487b9})},
- {Sign::POS, -129, MType({0x163ceae88f720f1e, 0x86216b3b0b17188b})},
- {Sign::POS, -129, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
- {Sign::POS, -129, MType({0xf7a5168126a58b9a, 0x8b5ae65d67db9acd})},
- {Sign::POS, -129, MType({0x5147bdb6ddcaf59c, 0x8dfccb1ad35ca6ed})},
- {Sign::POS, -129, MType({0xae91aeba609c8877, 0x90a22b6875c6a1f7})},
- {Sign::POS, -129, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -129, MType({0x4a5004f3ef063313, 0x95f783e6e49a9cfa})},
- {Sign::POS, -129, MType({0xd878bbe3d392be25, 0x9b5b3bb5f088b766})},
- {Sign::POS, -129, MType({0x5b035eae273a855f, 0x9e1293b9998c1daa})},
- {Sign::POS, -129, MType({0xbb2438273918db7e, 0xa0cda11eaf46390d})},
- {Sign::POS, -129, MType({0xf698298adddd7f32, 0xa38c6e138e20d831})},
- {Sign::POS, -129, MType({0xe4f5275c2d15c21f, 0xa64f04f0b961df76})},
- {Sign::POS, -129, MType({0x8164c759686a2209, 0xa9157039c51ebe70})},
- {Sign::POS, -129, MType({0xf72ea07749ce6bd3, 0xabdfba9e468fd6f6})},
- {Sign::POS, -129, MType({0x7dd6e688ebb13b03, 0xaeadeefacaf97d35})},
- {Sign::POS, -129, MType({0x18ce51fff99479cd, 0xb1801859d56249dc})},
- {Sign::POS, -129, MType({0x2756eba00bc33978, 0xb45641f4e350a0d3})},
- {Sign::POS, -129, MType({0xbe1116c3466beb6d, 0xb730773578cb90b2})},
- {Sign::POS, -129, MType({0x49dc60b2b059a60b, 0xba0ec3b633dd8b09})},
- {Sign::POS, -129, MType({0x2efd17781bb3afec, 0xbcf13343e7d9ec7d})},
- {Sign::POS, -129, MType({0x37eda996244bccb0, 0xbfd7d1dec0a8df6f})},
- {Sign::POS, -129, MType({0x33337789d592e296, 0xc2c2abbb6e5fd56f})},
- {Sign::POS, -129, MType({0x1a18fb8f9f9ef280, 0xc5b1cd44596fa51e})},
- {Sign::POS, -129, MType({0x688ce7c1a75e341a, 0xc8a5431adfb44ca5})},
- {Sign::POS, -129, MType({0x2d7e9307c70c0668, 0xcb9d1a189ab56e76})},
- {Sign::POS, -129, MType({0x2d7e9307c70c0668, 0xcb9d1a189ab56e76})},
- {Sign::POS, -129, MType({0xef2f3f4f861ad6a9, 0xce995f50af69d861})},
- {Sign::POS, -129, MType({0x7f9d79f51dcc7301, 0xd19a201127d3c645})},
- {Sign::POS, -129, MType({0x5f53bd2e406e66e7, 0xd49f69e456cf1b79})},
- {Sign::POS, -129, MType({0xad88bba7d0cee8e0, 0xd7a94a92466e833a})},
- {Sign::POS, -129, MType({0x96c20cca6efe2ac5, 0xdab7d02231484a92})},
- {Sign::POS, -129, MType({0xf40a666c87842843, 0xddcb08dc0717d85b})},
- {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
- {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
- {Sign::POS, -129, MType({0x3eadb651b49ac53a, 0xe3ffce3a2aa64922})},
- {Sign::POS, -129, MType({0x304e1653e71d9973, 0xe72178c0323a1a0f})},
- {Sign::POS, -129, MType({0xe9a767a80d6d97e8, 0xea481236f7d35baf})},
- {Sign::POS, -129, MType({0x4f91cf4b33e42998, 0xed73aa4264b0ade9})},
- {Sign::POS, -129, MType({0x4f91cf4b33e42998, 0xed73aa4264b0ade9})},
- {Sign::POS, -129, MType({0xfc66eb6408ff6433, 0xf0a450d139366ca6})},
- {Sign::POS, -129, MType({0xac8d42f78d3e65d3, 0xf3da161eed6b9aaf})},
- {Sign::POS, -129, MType({0x5a470250d40ebe90, 0xf7150ab5a09f27f4})},
- {Sign::POS, -129, MType({0x5a470250d40ebe90, 0xf7150ab5a09f27f4})},
- {Sign::POS, -129, MType({0xb780a545a1b54dcf, 0xfa553f7018c966f2})},
- {Sign::POS, -129, MType({0x8f05924d258c14c5, 0xfd9ac57bd244217e})},
- {Sign::POS, -128, MType({0x89d1b09c70c4010a, 0x8072d72d903d588b})},
- {Sign::POS, -128, MType({0x89d1b09c70c4010a, 0x8072d72d903d588b})},
- {Sign::POS, -128, MType({0x30d58c3f7e2ea1f, 0x821b05f3b01d6774})},
- {Sign::POS, -128, MType({0x20f6fafe8fbb68b9, 0x83c5f8299e2b4091})},
- {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
- {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
- {Sign::POS, -128, MType({0x1e005d06dbfa8f8, 0x87244c308e670a66})},
- {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
- {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
- {Sign::POS, -128, MType({0x2eb628dba173c82d, 0x8a8e1fb794b09134})},
- {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
- {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
- {Sign::POS, -128, MType({0xbddae1ccce247838, 0x8e03c24d73003959})},
- {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
- {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
- {Sign::POS, -128, MType({0x9b92199ed1a4bab1, 0x918586c5f5e4bf01})},
- {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
- {Sign::POS, -128, MType({0xf3cbc416a2418012, 0x9513c36876083695})},
- {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
- {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
- {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
- {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
- {Sign::POS, -128, MType({0xe549f9aaea3cb5e1, 0x9a81456cec642e0f})},
- {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
- {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
- {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
- {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
- {Sign::POS, -128, MType({0x67879c5a30cd1242, 0xa00ce1092e5498c3})},
- {Sign::POS, -128, MType({0x67879c5a30cd1242, 0xa00ce1092e5498c3})},
- {Sign::POS, -128, MType({0xb7efae08e597e16, 0xa1ecff97c91e267b})},
- {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
- {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
- {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
- {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
- {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
- {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
- {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
- {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
- {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
- {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
- {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
- {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
- {Sign::POS, -128, MType({0x66d235ee63073dd, 0xaf74155120c9011c})},
- {Sign::POS, -128, MType({0x66d235ee63073dd, 0xaf74155120c9011c})},
- {Sign::POS, 0, MType(0)},
+// print("{Sign::POS,", e, ", format_hex(m), "},");
+constexpr Float128 LOG_R1[129] = {
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -134, 0x8080abac'46f38946'662d417c'ed007a46_u128},
+ {Sign::POS, -133, 0x8102b2c4'9ac23a4f'91d082dc'e3ddcd38_u128},
+ {Sign::POS, -133, 0xc2492946'4655f45c'da5f3cc0'b3251dbd_u128},
+ {Sign::POS, -132, 0x820aec4f'3a222380'b9e3aea6'c444ef07_u128},
+ {Sign::POS, -132, 0xa33576a1'6f1f4c64'521016bd'904dc968_u128},
+ {Sign::POS, -132, 0xb3e4a796'a5dac208'27cca0bc'c06c2f92_u128},
+ {Sign::POS, -132, 0xd5779687'd887e0d1'a9dda170'56e45ed5_u128},
+ {Sign::POS, -132, 0xf7518e00'35c3dd83'606d8909'3278a939_u128},
+ {Sign::POS, -131, 0x8cb9de8a'32ab368a'a7c98595'30a45153_u128},
+ {Sign::POS, -131, 0x9defad3e'8f73217a'976d3b5b'45f6ca0b_u128},
+ {Sign::POS, -131, 0xa6988ae9'03f562ed'3e858f08'597b3a69_u128},
+ {Sign::POS, -131, 0xb8069857'560707a3'6a677b4c'8bec22e1_u128},
+ {Sign::POS, -131, 0xc99af2ea'ca4c4570'eaf51f66'692844ba_u128},
+ {Sign::POS, -131, 0xd273b205'8de1bd49'46bbf837'b4d320c6_u128},
+ {Sign::POS, -131, 0xe442c00d'e2591b47'196ab34c'e0bccd12_u128},
+ {Sign::POS, -131, 0xed393b1c'22351280'3f4e2e66'0317d55f_u128},
+ {Sign::POS, -131, 0xff4489ce'deab2ca6'c17bd40d'8d9291ec_u128},
+ {Sign::POS, -130, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
+ {Sign::POS, -130, 0x8d515bf1'1fb94f1c'88713268'840cbcc0_u128},
+ {Sign::POS, -130, 0x968b0864'3409ceb6'65c0da50'6a088484_u128},
+ {Sign::POS, -130, 0x9b2fe580'ac80b17d'411a5b94'4aca8708_u128},
+ {Sign::POS, -130, 0xa489ec19'9dab06f2'a9fb6cf0'ecb411b7_u128},
+ {Sign::POS, -130, 0xa93f2f25'0dac67d1'cad2fb8d'48054ae0_u128},
+ {Sign::POS, -130, 0xadfa035a'a1ed8fdc'149767e4'10316d2c_u128},
+ {Sign::POS, -130, 0xb780945b'ab55dce4'34c7bc3d'32750fde_u128},
+ {Sign::POS, -130, 0xbc4c6c2a'226399ef'8f6ebcfb'2016a439_u128},
+ {Sign::POS, -130, 0xc5f57f59'c7f46155'aa8b6997'a402bf30_u128},
+ {Sign::POS, -130, 0xcad2d6e7'b80bf914'2c507fb7'a3d0bf6a_u128},
+ {Sign::POS, -130, 0xcfb62038'44b3209a'd0cb02f3'3f79c16c_u128},
+ {Sign::POS, -130, 0xd98ec2ba'de71e539'58a98f2a'd65bee9b_u128},
+ {Sign::POS, -130, 0xde8439c1'dec56877'4d57da94'5b5d0aaa_u128},
+ {Sign::POS, -130, 0xe37fde37'807b84e3'4e9a750b'6b68781d_u128},
+ {Sign::POS, -130, 0xe881bf93'2af3dac0'c524848e'3443e040_u128},
+ {Sign::POS, -130, 0xf29877ff'38809091'3b020fa1'820c9492_u128},
+ {Sign::POS, -130, 0xf7ad6f26'e7ff2ef7'54d2238f'75f969b1_u128},
+ {Sign::POS, -130, 0xfcc8e365'9d9bcbec'ca0cdf30'1431b60f_u128},
+ {Sign::POS, -129, 0x80f572b1'363487b9'f5bd0b5b'3479d5f4_u128},
+ {Sign::POS, -129, 0x86216b3b'0b17188b'163ceae8'8f720f1e_u128},
+ {Sign::POS, -129, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
+ {Sign::POS, -129, 0x8b5ae65d'67db9acd'f7a51681'26a58b9a_u128},
+ {Sign::POS, -129, 0x8dfccb1a'd35ca6ed'5147bdb6'ddcaf59c_u128},
+ {Sign::POS, -129, 0x90a22b68'75c6a1f7'ae91aeba'609c8877_u128},
+ {Sign::POS, -129, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -129, 0x95f783e6'e49a9cfa'4a5004f3'ef063313_u128},
+ {Sign::POS, -129, 0x9b5b3bb5'f088b766'd878bbe3'd392be25_u128},
+ {Sign::POS, -129, 0x9e1293b9'998c1daa'5b035eae'273a855f_u128},
+ {Sign::POS, -129, 0xa0cda11e'af46390d'bb243827'3918db7e_u128},
+ {Sign::POS, -129, 0xa38c6e13'8e20d831'f698298a'dddd7f32_u128},
+ {Sign::POS, -129, 0xa64f04f0'b961df76'e4f5275c'2d15c21f_u128},
+ {Sign::POS, -129, 0xa9157039'c51ebe70'8164c759'686a2209_u128},
+ {Sign::POS, -129, 0xabdfba9e'468fd6f6'f72ea077'49ce6bd3_u128},
+ {Sign::POS, -129, 0xaeadeefa'caf97d35'7dd6e688'ebb13b03_u128},
+ {Sign::POS, -129, 0xb1801859'd56249dc'18ce51ff'f99479cd_u128},
+ {Sign::POS, -129, 0xb45641f4'e350a0d3'2756eba0'0bc33978_u128},
+ {Sign::POS, -129, 0xb7307735'78cb90b2'be1116c3'466beb6d_u128},
+ {Sign::POS, -129, 0xba0ec3b6'33dd8b09'49dc60b2'b059a60b_u128},
+ {Sign::POS, -129, 0xbcf13343'e7d9ec7d'2efd1778'1bb3afec_u128},
+ {Sign::POS, -129, 0xbfd7d1de'c0a8df6f'37eda996'244bccb0_u128},
+ {Sign::POS, -129, 0xc2c2abbb'6e5fd56f'33337789'd592e296_u128},
+ {Sign::POS, -129, 0xc5b1cd44'596fa51e'1a18fb8f'9f9ef280_u128},
+ {Sign::POS, -129, 0xc8a5431a'dfb44ca5'688ce7c1'a75e341a_u128},
+ {Sign::POS, -129, 0xcb9d1a18'9ab56e76'2d7e9307'c70c0668_u128},
+ {Sign::POS, -129, 0xcb9d1a18'9ab56e76'2d7e9307'c70c0668_u128},
+ {Sign::POS, -129, 0xce995f50'af69d861'ef2f3f4f'861ad6a9_u128},
+ {Sign::POS, -129, 0xd19a2011'27d3c645'7f9d79f5'1dcc7301_u128},
+ {Sign::POS, -129, 0xd49f69e4'56cf1b79'5f53bd2e'406e66e7_u128},
+ {Sign::POS, -129, 0xd7a94a92'466e833a'ad88bba7'd0cee8e0_u128},
+ {Sign::POS, -129, 0xdab7d022'31484a92'96c20cca'6efe2ac5_u128},
+ {Sign::POS, -129, 0xddcb08dc'0717d85b'f40a666c'87842843_u128},
+ {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
+ {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
+ {Sign::POS, -129, 0xe3ffce3a'2aa64922'3eadb651'b49ac53a_u128},
+ {Sign::POS, -129, 0xe72178c0'323a1a0f'304e1653'e71d9973_u128},
+ {Sign::POS, -129, 0xea481236'f7d35baf'e9a767a8'0d6d97e8_u128},
+ {Sign::POS, -129, 0xed73aa42'64b0ade9'4f91cf4b'33e42998_u128},
+ {Sign::POS, -129, 0xed73aa42'64b0ade9'4f91cf4b'33e42998_u128},
+ {Sign::POS, -129, 0xf0a450d1'39366ca6'fc66eb64'08ff6433_u128},
+ {Sign::POS, -129, 0xf3da161e'ed6b9aaf'ac8d42f7'8d3e65d3_u128},
+ {Sign::POS, -129, 0xf7150ab5'a09f27f4'5a470250'd40ebe90_u128},
+ {Sign::POS, -129, 0xf7150ab5'a09f27f4'5a470250'd40ebe90_u128},
+ {Sign::POS, -129, 0xfa553f70'18c966f2'b780a545'a1b54dcf_u128},
+ {Sign::POS, -129, 0xfd9ac57b'd244217e'8f05924d'258c14c5_u128},
+ {Sign::POS, -128, 0x8072d72d'903d588b'89d1b09c'70c4010a_u128},
+ {Sign::POS, -128, 0x8072d72d'903d588b'89d1b09c'70c4010a_u128},
+ {Sign::POS, -128, 0x821b05f3'b01d6774'030d58c3'f7e2ea1f_u128},
+ {Sign::POS, -128, 0x83c5f829'9e2b4091'20f6fafe'8fbb68b9_u128},
+ {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
+ {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
+ {Sign::POS, -128, 0x87244c30'8e670a66'01e005d0'6dbfa8f8_u128},
+ {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
+ {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
+ {Sign::POS, -128, 0x8a8e1fb7'94b09134'2eb628db'a173c82d_u128},
+ {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
+ {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
+ {Sign::POS, -128, 0x8e03c24d'73003959'bddae1cc'ce247838_u128},
+ {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
+ {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
+ {Sign::POS, -128, 0x918586c5'f5e4bf01'9b92199e'd1a4bab1_u128},
+ {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
+ {Sign::POS, -128, 0x9513c368'76083695'f3cbc416'a2418012_u128},
+ {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
+ {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
+ {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
+ {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
+ {Sign::POS, -128, 0x9a81456c'ec642e0f'e549f9aa'ea3cb5e1_u128},
+ {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
+ {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
+ {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
+ {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
+ {Sign::POS, -128, 0xa00ce109'2e5498c3'67879c5a'30cd1242_u128},
+ {Sign::POS, -128, 0xa00ce109'2e5498c3'67879c5a'30cd1242_u128},
+ {Sign::POS, -128, 0xa1ecff97'c91e267b'0b7efae0'8e597e16_u128},
+ {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
+ {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
+ {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
+ {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
+ {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
+ {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
+ {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
+ {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
+ {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
+ {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
+ {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
+ {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
+ {Sign::POS, -128, 0xaf741551'20c9011c'066d235e'e63073dd_u128},
+ {Sign::POS, -128, 0xaf741551'20c9011c'066d235e'e63073dd_u128},
+ {Sign::POS, 0, 0_u128},
};
// Logarithm range reduction - Step 2:
@@ -431,196 +435,196 @@ constexpr double S2[198] = {
// r = 2^-18 * round( 2^18 / (1 + i*2^(-14)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
// print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
-// MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
-const Float128 LOG_R2[198] = {
- {Sign::NEG, -135, MType({0xa0e061c5f7431c5e, 0xb67dab2a1a5742a4})},
- {Sign::NEG, -135, MType({0x5d5bfe7b969ed6ec, 0xb4807f24af682939})},
- {Sign::NEG, -135, MType({0x4d08702ddfabc23f, 0xb2834b35b4d54d5f})},
- {Sign::NEG, -135, MType({0xd4d366508b9953df, 0xb0860f5ceba9be95})},
- {Sign::NEG, -135, MType({0xac18a289f8f214a9, 0xae68f71aa09e8847})},
- {Sign::NEG, -135, MType({0xd5b42054abb88c45, 0xac6baaeed676e8f1})},
- {Sign::NEG, -135, MType({0x9809d58ee484964, 0xaa6e56d87cd632d6})},
- {Sign::NEG, -135, MType({0xb9e6fc7c72f06d73, 0xa870fad754bb8791})},
- {Sign::NEG, -135, MType({0x6f78d6d0105c00e2, 0xa67396eb1f231892})},
- {Sign::NEG, -135, MType({0x28f712629209148, 0xa4762b139d0626e7})},
- {Sign::NEG, -135, MType({0xc98d898ef172df02, 0xa258dfd10aedaa67})},
- {Sign::NEG, -135, MType({0xfcc37c3c3062bfa1, 0xa05b63a373e60a83})},
- {Sign::NEG, -135, MType({0x3eb450db05763c36, 0x9e5ddf89cf42f501})},
- {Sign::NEG, -135, MType({0x7146a86fd458b775, 0x9c605383ddf1b88c})},
- {Sign::NEG, -135, MType({0xc20a0c9281474436, 0x9a62bf9160dcb286})},
- {Sign::NEG, -135, MType({0xcdc57316ec4aebc3, 0x986523b218eb4ed6})},
- {Sign::NEG, -135, MType({0xc060dad74cef4273, 0x96677fe5c70207b9})},
- {Sign::NEG, -135, MType({0xed8def1a3e433499, 0x9449f92d2ff44633})},
- {Sign::NEG, -135, MType({0x3ce7a1f85c27b4fc, 0x924c45073220b5e0})},
- {Sign::NEG, -135, MType({0xf2ca893449f7f2cb, 0x904e88f368fea63f})},
- {Sign::NEG, -135, MType({0x8d77d9fabd2853cf, 0x8e50c4f1956699ed})},
- {Sign::NEG, -135, MType({0x93e828d75b58ded4, 0x8c52f901782e20ec})},
- {Sign::NEG, -135, MType({0x9f9605b053c5acf0, 0x8a552522d227d87a})},
- {Sign::NEG, -135, MType({0x62a149393bca7241, 0x8857495564236ae0})},
- {Sign::NEG, -135, MType({0xaea6b56ce89203d4, 0x86398719b66bac7c})},
- {Sign::NEG, -135, MType({0x242bd86d00609b2, 0x843b9aef044e4dcc})},
- {Sign::NEG, -135, MType({0xdaabf92774bac84e, 0x823da6d4c89c6927})},
- {Sign::NEG, -135, MType({0xa1c6f3fc242ef8d0, 0x803faacac419abf2})},
- {Sign::NEG, -136, MType({0xa225ebc02e6d9dd4, 0xfc834da16f0d9f57})},
- {Sign::NEG, -136, MType({0xc33f6ad340ae18a9, 0xf88735ccc7433381})},
- {Sign::NEG, -136, MType({0x70b2a4d38a242244, 0xf48b0e171249b6bc})},
- {Sign::NEG, -136, MType({0x1d54819048b811b0, 0xf08ed67fd190e280})},
- {Sign::NEG, -136, MType({0x9c21b650afe9ede0, 0xec52ca07ed95f236})},
- {Sign::NEG, -136, MType({0x935519c96d30e463, 0xe85671adecd28aac})},
- {Sign::NEG, -136, MType({0xba88f6f2e2672cfe, 0xe45a0970dc912ca7})},
- {Sign::NEG, -136, MType({0xb1a8b84657ae069, 0xe05d91503e298bc8})},
- {Sign::NEG, -136, MType({0xea3bff8d197b20a1, 0xdc61094b92ed70ef})},
- {Sign::NEG, -136, MType({0xcdbb931d6fecc249, 0xd86471625c28b9e5})},
- {Sign::NEG, -136, MType({0xd971d560d5f00820, 0xd467c9941b2158f5})},
- {Sign::NEG, -136, MType({0x75563561244c090b, 0xd06b11e051175493})},
- {Sign::NEG, -136, MType({0xdc393c9a3f3b380f, 0xcc6e4a467f44c6fa})},
- {Sign::NEG, -136, MType({0xe6abe6e9e4ee2096, 0xc831a4c6f6fa709d})},
- {Sign::NEG, -136, MType({0x3ce3c8228583a66e, 0xc434bc6124a0f16e})},
- {Sign::NEG, -136, MType({0xb96a79f5c5a4963a, 0xc037c413c61bfd93})},
- {Sign::NEG, -136, MType({0xaaef27337008679f, 0xbc3abbde5c8d9bde})},
- {Sign::NEG, -136, MType({0xa49a3fcaddc8bc5a, 0xb83da3c06911e509})},
- {Sign::NEG, -136, MType({0xe0254feb785362fa, 0xb4407bb96cbf035a})},
- {Sign::NEG, -136, MType({0x9893a4e25ab9dc95, 0xb04343c8e8a53245})},
- {Sign::NEG, -136, MType({0x5d8b0f40a3708915, 0xac45fbee5dcebe0b})},
- {Sign::NEG, -136, MType({0x5f4c11c2c7a58c69, 0xa848a4294d40035d})},
- {Sign::NEG, -136, MType({0xb348cc5df706ffba, 0xa44b3c7937f76efd})},
- {Sign::NEG, -136, MType({0x9159f2c55a18befd, 0xa04dc4dd9eed7d60})},
- {Sign::NEG, -136, MType({0xbdfdee41fe6a5a02, 0x9c1064563058bef3})},
- {Sign::NEG, -136, MType({0x4580ddf89853254d, 0x9812cbe346475a24})},
- {Sign::NEG, -136, MType({0xac75e10d61fc3ee8, 0x9415238353489ffb})},
- {Sign::NEG, -136, MType({0xcad9b30b29736155, 0x90176b35d83ce8e2})},
- {Sign::NEG, -136, MType({0x6f881deb98fc45f3, 0x8c19a2fa55fe9b14})},
- {Sign::NEG, -136, MType({0x70a04b63b7248c96, 0x881bcad04d622a3e})},
- {Sign::NEG, -136, MType({0xb4823fb48035eddd, 0x841de2b73f361722})},
- {Sign::NEG, -136, MType({0x3364ccb5b13cd47f, 0x801feaaeac42ef38})},
- {Sign::NEG, -137, MType({0xe306977b049f0ad5, 0xf843c56c2a969897})},
- {Sign::NEG, -137, MType({0xe3c4d9e9619bc045, 0xf0479599f617a843})},
- {Sign::NEG, -137, MType({0x4356d525b5e6432d, 0xe84b45e5bc76702c})},
- {Sign::NEG, -137, MType({0x7839dcd7989339ab, 0xe04ed64e7f14697a})},
- {Sign::NEG, -137, MType({0x4e21f045ecb76f23, 0xd85246d33f47230b})},
- {Sign::NEG, -137, MType({0x902e248dd4ba9b28, 0xd0559772fe5840b0})},
- {Sign::NEG, -137, MType({0xa44449067ef92e01, 0xc858c82cbd857a72})},
- {Sign::NEG, -137, MType({0x17926207cc22e4e6, 0xc05bd8ff7e009bd2})},
- {Sign::NEG, -137, MType({0x1c349622f3fa5d82, 0xb85ec9ea40ef8309})},
- {Sign::NEG, -137, MType({0x97fa2fd0c9dc723e, 0xafe1c6ece1a058dd})},
- {Sign::NEG, -137, MType({0x983e80897cf1e60f, 0xa7e47606048b1a65})},
- {Sign::NEG, -137, MType({0x7199cd06ae5d39b3, 0x9fe705341d236102})},
- {Sign::NEG, -137, MType({0x43cd18a72a051a96, 0x97e974762c5e8f58})},
- {Sign::NEG, -137, MType({0x7b6d1248c3e1fd40, 0x8febc3cb332616ff})},
- {Sign::NEG, -137, MType({0xf5572a8814c703af, 0x87edf332325777c5})},
- {Sign::NEG, -138, MType({0x26828c92649a3a39, 0xffe0055455887de0})},
- {Sign::NEG, -138, MType({0x82c550bd1216d82a, 0xefe3e4643a640cf3})},
- {Sign::NEG, -138, MType({0xda6959f7f0e01bf0, 0xdfe7839214b4e8ae})},
- {Sign::NEG, -138, MType({0xda93e2fa85a8f214, 0xcfeae2dbe5d6736d})},
- {Sign::NEG, -138, MType({0xb47505bfa5a03b06, 0xbfee023faf0c2480})},
- {Sign::NEG, -138, MType({0xb1475a5180a43520, 0xaff0e1bb718186ad})},
- {Sign::NEG, -138, MType({0xa8740b91c95df537, 0x9ff3814d2e4a36b2})},
- {Sign::NEG, -138, MType({0x57d895d35921b59c, 0x8ff5e0f2e661e1c6})},
- {Sign::NEG, -139, MType({0x3c56c598c659c2a3, 0xfff0015535588833})},
- {Sign::NEG, -139, MType({0x2ef8ec33ed9d782a, 0xdff3c0e497ea4eb1})},
- {Sign::NEG, -139, MType({0x379eba7e6465ff63, 0xbff7008ff5e0c257})},
- {Sign::NEG, -139, MType({0x3f972b783fcab757, 0x9ff9c0535073a370})},
- {Sign::NEG, -140, MType({0xde026e271ee0549d, 0xfff8005551558885})},
- {Sign::NEG, -140, MType({0xeceb47ea01f6c632, 0xbffb8023febc0c25})},
- {Sign::NEG, -141, MType({0x7333c57857e1ed52, 0xfffc001554d55888})},
- {Sign::NEG, -142, MType({0x87dde026fa704374, 0xfffe000555455588})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -141, MType({0x44999abe2fe2cc65, 0x80010002aab2aac4})},
- {Sign::POS, -140, MType({0x4eef381581464ccb, 0x8002000aaaeaac44})},
- {Sign::POS, -140, MType({0xdfeb485085f6f454, 0xc004802401440c26})},
- {Sign::POS, -139, MType({0x99abe3be3a1c6e93, 0x8004002aacaac445})},
- {Sign::POS, -139, MType({0x6bc1e20eac8448b4, 0xa00640535a37a37a})},
- {Sign::POS, -139, MType({0x979eedc064c242fd, 0xc00900900a20c275})},
- {Sign::POS, -139, MType({0xc72446cc1bf728bd, 0xe00c40e4bd6e4efd})},
- {Sign::POS, -138, MType({0xf381b821bbb569e5, 0x800800aabaac446e})},
- {Sign::POS, -138, MType({0x569b26aaa485ea5c, 0x900a20f319a3e273})},
- {Sign::POS, -138, MType({0x2dcf56c83c80b028, 0xa00c814d7c6a37f8})},
- {Sign::POS, -138, MType({0x5f69768284463b9b, 0xb00f21bbe3e388ee})},
- {Sign::POS, -138, MType({0xb48ea6c05e2773a1, 0xc0120240510c284c})},
- {Sign::POS, -138, MType({0x14d9d76196d8043a, 0xd01522dcc4f87991})},
- {Sign::POS, -138, MType({0xe016a611a4415d72, 0xe018839340d4f241})},
- {Sign::POS, -138, MType({0x661e135f49a47c40, 0xf01c2465c5e61b6f})},
- {Sign::POS, -137, MType({0xbe6bf0fa435e8383, 0x801002ab2ac4499a})},
- {Sign::POS, -137, MType({0x9a31ba0cbc030353, 0x881213337898871e})},
- {Sign::POS, -137, MType({0x54b57dfe0c4c840f, 0x901443cccd362c9f})},
- {Sign::POS, -137, MType({0x7ad1e9c315328f7e, 0x98169478296fad41})},
- {Sign::POS, -137, MType({0x1f3f686cf3d6be22, 0xa01905368e2389b3})},
- {Sign::POS, -137, MType({0xf105b66ec4703ede, 0xa81b9608fc3c50ec})},
- {Sign::POS, -137, MType({0x610848c68df4d233, 0xb01e46f074b0a0f3})},
- {Sign::POS, -137, MType({0x2e0efddf33a20464, 0xb7a0e9ed7613acb0})},
- {Sign::POS, -137, MType({0xc2cdb3c750f127b4, 0xbfa3d9008e042ffb})},
- {Sign::POS, -137, MType({0xbd9533786d3f4c49, 0xc7a6e82ba36a7073})},
- {Sign::POS, -137, MType({0x82e237c9a4d450e3, 0xcfaa176fb76c8eb1})},
- {Sign::POS, -137, MType({0xc00b46a4d0e3dfd0, 0xd7ad66cdcb3cbe14})},
- {Sign::POS, -137, MType({0xea999c0df8546710, 0xdfb0d646e0194584})},
- {Sign::POS, -137, MType({0xcec6c2a9ad974f4f, 0xe7b465dbf74c8032})},
- {Sign::POS, -137, MType({0x2d2045da1570a07c, 0xefb8158e122cde5a})},
- {Sign::POS, -137, MType({0x6752e9b2381e3edc, 0xf7bbe55e321ce603})},
- {Sign::POS, -137, MType({0x3c1ed52728e00e40, 0xffbfd54d588b33c5})},
- {Sign::POS, -136, MType({0x493b0d873fb9a340, 0x83e1f2ae43793dc3})},
- {Sign::POS, -136, MType({0x29e38750c9d26893, 0x87e40ac65f6cc4a0})},
- {Sign::POS, -136, MType({0xaab9e8327258ac3f, 0x8be632ef80e9a0df})},
- {Sign::POS, -136, MType({0x28bc403d8a5f3c63, 0x8fe86b2a28bf51b3})},
- {Sign::POS, -136, MType({0xf720c1c97227fcdc, 0x93eab376d7c36377})},
- {Sign::POS, -136, MType({0x6ad9a3e3d11b66c1, 0x97ed0bd60ed17018})},
- {Sign::POS, -136, MType({0xedb27b79c90b4019, 0x9bef74484ecb1f6c})},
- {Sign::POS, -136, MType({0xa092a0d7ab21722a, 0x9fb1c4cd27012e19})},
- {Sign::POS, -136, MType({0x535d52f0939a4d02, 0xa3b44c65b71c2d85})},
- {Sign::POS, -136, MType({0x90a57e11edc1864e, 0xa7b6e412cadcb3dc})},
- {Sign::POS, -136, MType({0x68e9c90160031159, 0xabb98bd4e33c4381})},
- {Sign::POS, -136, MType({0xbf60594f929adeb8, 0xafbc43ac813a6ea3})},
- {Sign::POS, -136, MType({0x8a42158886775205, 0xb3bf0b9a25dcd7a2})},
- {Sign::POS, -136, MType({0x1ab45417663dee9e, 0xb7c1e39e522f316d})},
- {Sign::POS, -136, MType({0x6c51ae3ce1aea68a, 0xbbc4cbb987433fe4})},
- {Sign::POS, -136, MType({0x7c52ae8b40ebabb7, 0xbfc7c3ec4630d83c})},
- {Sign::POS, -136, MType({0xa857126f7cfaaa67, 0xc3cacc371015e15d})},
- {Sign::POS, -136, MType({0x14d05662cd29464a, 0xc7cde49a66165446})},
- {Sign::POS, -136, MType({0x8379db06ef3cd6bb, 0xcb90da1644d29bb7})},
- {Sign::POS, -136, MType({0x9025f4c67dd38bb6, 0xcf9411aa99ddb7de})},
- {Sign::POS, -136, MType({0xd6f8a61c892032ee, 0xd3975958f681086d})},
- {Sign::POS, -136, MType({0x9a2f20b4e2332d47, 0xd79ab121dbf8714c})},
- {Sign::POS, -136, MType({0x3c767d61f51d375b, 0xdb9e1905cb85ea59})},
- {Sign::POS, -136, MType({0xd4b2bd65bb25493c, 0xdfa1910546717fca})},
- {Sign::POS, -136, MType({0xc96c1254a30ef91f, 0xe3a51920ce095292})},
- {Sign::POS, -136, MType({0x73e324ce0946b214, 0xe7a8b158e3a198be})},
- {Sign::POS, -136, MType({0xcacd125a12bac62c, 0xebac59ae08949dd8})},
- {Sign::POS, -136, MType({0xcafdc27227b71eaa, 0xef6fd620b2b7a503})},
- {Sign::POS, -136, MType({0x688d4282f6026aa3, 0xf3739daf959aaafc})},
- {Sign::POS, -136, MType({0xe54e9e3804464cdd, 0xf777755d03f4e0b6})},
- {Sign::POS, -136, MType({0xcb78b383f4b59dce, 0xfb7b5d297f388a12})},
- {Sign::POS, -136, MType({0xee055fc515062c04, 0xff7f551588de024f})},
- {Sign::POS, -135, MType({0x207812b43382acdd, 0x81c1ae90d131de38})},
- {Sign::POS, -135, MType({0xdc90c4c4b61f3a87, 0x83c3baa726a721cc})},
- {Sign::POS, -135, MType({0x1a03f13fb2c978b1, 0x85c5cece05941dbc})},
- {Sign::POS, -135, MType({0xb36f282e83a7dc36, 0x87c7eb05aec1304f})},
- {Sign::POS, -135, MType({0xd82a46616d4c393f, 0x89a9eccd56a980c0})},
- {Sign::POS, -135, MType({0xbc6ff84713c9babd, 0x8bac18a640185360})},
- {Sign::POS, -135, MType({0x9f7942a516fc2d8a, 0x8dae4c90b22574f4})},
- {Sign::POS, -135, MType({0x15e50cfd9b29b427, 0x8fb0888ceda546ab})},
- {Sign::POS, -135, MType({0x9f465296ae7dd49a, 0x91b2cc9b336f3718})},
- {Sign::POS, -135, MType({0xb49c1eb9b348e6e4, 0x93b518bbc45dc268})},
- {Sign::POS, -135, MType({0xdaa320cd64c9d9c7, 0x95b76ceee14e728e})},
- {Sign::POS, -135, MType({0x75a91950ffe1e3b5, 0x9799a333de49b963})},
- {Sign::POS, -135, MType({0x5c6abcbf43f03f14, 0x999c070ba32068cd})},
- {Sign::POS, -135, MType({0x5a9e7f265d1ed157, 0x9b9e72f6b295ad4f})},
- {Sign::POS, -135, MType({0xefeb98d02a195c17, 0x9da0e6f54d9318fd})},
- {Sign::POS, -135, MType({0x2aa503a3110ab5a7, 0x9fa36307b5054ca8})},
- {Sign::POS, -135, MType({0xd0fe7e05869eb825, 0xa1a5e72e29dbf808})},
- {Sign::POS, -135, MType({0xe80a28f4e1e500d2, 0xa3884a68a750cb10})},
- {Sign::POS, -135, MType({0x531064151ca6e30b, 0xa58ade36aeef9f0b})},
- {Sign::POS, -135, MType({0x27c01ffa8e2e3c4b, 0xa78d7a1982c4b08f})},
- {Sign::POS, -135, MType({0x7ba9408dc857d568, 0xa9901e1163cbbbf5})},
- {Sign::POS, -135, MType({0x104d1e3331d3b4fa, 0xab92ca1e93038d76})},
- {Sign::POS, -135, MType({0x9343c846fcdf9137, 0xad957e41516e0158})},
- {Sign::POS, -135, MType({0x3977e89aec59bfa2, 0xaf780e79b2514889})},
- {Sign::POS, -135, MType({0x913d4e3dc55c3e6e, 0xb17ad246ef3713bc})},
- {Sign::POS, -135, MType({0x777b52a9e70d8bcc, 0xb37d9e2a7a56b09d})},
- {Sign::POS, -135, MType({0x55de916fd30591de, 0xb580722494be0c91})},
- {Sign::POS, -135, MType({0xe79cfb37be2861e4, 0xb7834e357f7e2600})},
- {Sign::POS, -135, MType({0x90983104d3805389, 0xb986325d7bab0c89})},
- {Sign::POS, -135, MType({0x59e3b2ec71ce64f4, 0xbb68ef9c254aa378})},
- {Sign::POS, -135, MType({0xe83183bf3dd612ef, 0xbd6be3718c77636f})},
- {Sign::POS, -135, MType({0xc4e3b0ac2fd52b7f, 0xbf6edf5ec44d9d35})},
+// format_hex(m), "},");
+constexpr Float128 LOG_R2[198] = {
+ {Sign::NEG, -135, 0xb67dab2a'1a5742a4'a0e061c5'f7431c5e_u128},
+ {Sign::NEG, -135, 0xb4807f24'af682939'5d5bfe7b'969ed6ec_u128},
+ {Sign::NEG, -135, 0xb2834b35'b4d54d5f'4d08702d'dfabc23f_u128},
+ {Sign::NEG, -135, 0xb0860f5c'eba9be95'd4d36650'8b9953df_u128},
+ {Sign::NEG, -135, 0xae68f71a'a09e8847'ac18a289'f8f214a9_u128},
+ {Sign::NEG, -135, 0xac6baaee'd676e8f1'd5b42054'abb88c45_u128},
+ {Sign::NEG, -135, 0xaa6e56d8'7cd632d6'09809d58'ee484964_u128},
+ {Sign::NEG, -135, 0xa870fad7'54bb8791'b9e6fc7c'72f06d73_u128},
+ {Sign::NEG, -135, 0xa67396eb'1f231892'6f78d6d0'105c00e2_u128},
+ {Sign::NEG, -135, 0xa4762b13'9d0626e7'028f7126'29209148_u128},
+ {Sign::NEG, -135, 0xa258dfd1'0aedaa67'c98d898e'f172df02_u128},
+ {Sign::NEG, -135, 0xa05b63a3'73e60a83'fcc37c3c'3062bfa1_u128},
+ {Sign::NEG, -135, 0x9e5ddf89'cf42f501'3eb450db'05763c36_u128},
+ {Sign::NEG, -135, 0x9c605383'ddf1b88c'7146a86f'd458b775_u128},
+ {Sign::NEG, -135, 0x9a62bf91'60dcb286'c20a0c92'81474436_u128},
+ {Sign::NEG, -135, 0x986523b2'18eb4ed6'cdc57316'ec4aebc3_u128},
+ {Sign::NEG, -135, 0x96677fe5'c70207b9'c060dad7'4cef4273_u128},
+ {Sign::NEG, -135, 0x9449f92d'2ff44633'ed8def1a'3e433499_u128},
+ {Sign::NEG, -135, 0x924c4507'3220b5e0'3ce7a1f8'5c27b4fc_u128},
+ {Sign::NEG, -135, 0x904e88f3'68fea63f'f2ca8934'49f7f2cb_u128},
+ {Sign::NEG, -135, 0x8e50c4f1'956699ed'8d77d9fa'bd2853cf_u128},
+ {Sign::NEG, -135, 0x8c52f901'782e20ec'93e828d7'5b58ded4_u128},
+ {Sign::NEG, -135, 0x8a552522'd227d87a'9f9605b0'53c5acf0_u128},
+ {Sign::NEG, -135, 0x88574955'64236ae0'62a14939'3bca7241_u128},
+ {Sign::NEG, -135, 0x86398719'b66bac7c'aea6b56c'e89203d4_u128},
+ {Sign::NEG, -135, 0x843b9aef'044e4dcc'0242bd86'd00609b2_u128},
+ {Sign::NEG, -135, 0x823da6d4'c89c6927'daabf927'74bac84e_u128},
+ {Sign::NEG, -135, 0x803faaca'c419abf2'a1c6f3fc'242ef8d0_u128},
+ {Sign::NEG, -136, 0xfc834da1'6f0d9f57'a225ebc0'2e6d9dd4_u128},
+ {Sign::NEG, -136, 0xf88735cc'c7433381'c33f6ad3'40ae18a9_u128},
+ {Sign::NEG, -136, 0xf48b0e17'1249b6bc'70b2a4d3'8a242244_u128},
+ {Sign::NEG, -136, 0xf08ed67f'd190e280'1d548190'48b811b0_u128},
+ {Sign::NEG, -136, 0xec52ca07'ed95f236'9c21b650'afe9ede0_u128},
+ {Sign::NEG, -136, 0xe85671ad'ecd28aac'935519c9'6d30e463_u128},
+ {Sign::NEG, -136, 0xe45a0970'dc912ca7'ba88f6f2'e2672cfe_u128},
+ {Sign::NEG, -136, 0xe05d9150'3e298bc8'0b1a8b84'657ae069_u128},
+ {Sign::NEG, -136, 0xdc61094b'92ed70ef'ea3bff8d'197b20a1_u128},
+ {Sign::NEG, -136, 0xd8647162'5c28b9e5'cdbb931d'6fecc249_u128},
+ {Sign::NEG, -136, 0xd467c994'1b2158f5'd971d560'd5f00820_u128},
+ {Sign::NEG, -136, 0xd06b11e0'51175493'75563561'244c090b_u128},
+ {Sign::NEG, -136, 0xcc6e4a46'7f44c6fa'dc393c9a'3f3b380f_u128},
+ {Sign::NEG, -136, 0xc831a4c6'f6fa709d'e6abe6e9'e4ee2096_u128},
+ {Sign::NEG, -136, 0xc434bc61'24a0f16e'3ce3c822'8583a66e_u128},
+ {Sign::NEG, -136, 0xc037c413'c61bfd93'b96a79f5'c5a4963a_u128},
+ {Sign::NEG, -136, 0xbc3abbde'5c8d9bde'aaef2733'7008679f_u128},
+ {Sign::NEG, -136, 0xb83da3c0'6911e509'a49a3fca'ddc8bc5a_u128},
+ {Sign::NEG, -136, 0xb4407bb9'6cbf035a'e0254feb'785362fa_u128},
+ {Sign::NEG, -136, 0xb04343c8'e8a53245'9893a4e2'5ab9dc95_u128},
+ {Sign::NEG, -136, 0xac45fbee'5dcebe0b'5d8b0f40'a3708915_u128},
+ {Sign::NEG, -136, 0xa848a429'4d40035d'5f4c11c2'c7a58c69_u128},
+ {Sign::NEG, -136, 0xa44b3c79'37f76efd'b348cc5d'f706ffba_u128},
+ {Sign::NEG, -136, 0xa04dc4dd'9eed7d60'9159f2c5'5a18befd_u128},
+ {Sign::NEG, -136, 0x9c106456'3058bef3'bdfdee41'fe6a5a02_u128},
+ {Sign::NEG, -136, 0x9812cbe3'46475a24'4580ddf8'9853254d_u128},
+ {Sign::NEG, -136, 0x94152383'53489ffb'ac75e10d'61fc3ee8_u128},
+ {Sign::NEG, -136, 0x90176b35'd83ce8e2'cad9b30b'29736155_u128},
+ {Sign::NEG, -136, 0x8c19a2fa'55fe9b14'6f881deb'98fc45f3_u128},
+ {Sign::NEG, -136, 0x881bcad0'4d622a3e'70a04b63'b7248c96_u128},
+ {Sign::NEG, -136, 0x841de2b7'3f361722'b4823fb4'8035eddd_u128},
+ {Sign::NEG, -136, 0x801feaae'ac42ef38'3364ccb5'b13cd47f_u128},
+ {Sign::NEG, -137, 0xf843c56c'2a969897'e306977b'049f0ad5_u128},
+ {Sign::NEG, -137, 0xf0479599'f617a843'e3c4d9e9'619bc045_u128},
+ {Sign::NEG, -137, 0xe84b45e5'bc76702c'4356d525'b5e6432d_u128},
+ {Sign::NEG, -137, 0xe04ed64e'7f14697a'7839dcd7'989339ab_u128},
+ {Sign::NEG, -137, 0xd85246d3'3f47230b'4e21f045'ecb76f23_u128},
+ {Sign::NEG, -137, 0xd0559772'fe5840b0'902e248d'd4ba9b28_u128},
+ {Sign::NEG, -137, 0xc858c82c'bd857a72'a4444906'7ef92e01_u128},
+ {Sign::NEG, -137, 0xc05bd8ff'7e009bd2'17926207'cc22e4e6_u128},
+ {Sign::NEG, -137, 0xb85ec9ea'40ef8309'1c349622'f3fa5d82_u128},
+ {Sign::NEG, -137, 0xafe1c6ec'e1a058dd'97fa2fd0'c9dc723e_u128},
+ {Sign::NEG, -137, 0xa7e47606'048b1a65'983e8089'7cf1e60f_u128},
+ {Sign::NEG, -137, 0x9fe70534'1d236102'7199cd06'ae5d39b3_u128},
+ {Sign::NEG, -137, 0x97e97476'2c5e8f58'43cd18a7'2a051a96_u128},
+ {Sign::NEG, -137, 0x8febc3cb'332616ff'7b6d1248'c3e1fd40_u128},
+ {Sign::NEG, -137, 0x87edf332'325777c5'f5572a88'14c703af_u128},
+ {Sign::NEG, -138, 0xffe00554'55887de0'26828c92'649a3a39_u128},
+ {Sign::NEG, -138, 0xefe3e464'3a640cf3'82c550bd'1216d82a_u128},
+ {Sign::NEG, -138, 0xdfe78392'14b4e8ae'da6959f7'f0e01bf0_u128},
+ {Sign::NEG, -138, 0xcfeae2db'e5d6736d'da93e2fa'85a8f214_u128},
+ {Sign::NEG, -138, 0xbfee023f'af0c2480'b47505bf'a5a03b06_u128},
+ {Sign::NEG, -138, 0xaff0e1bb'718186ad'b1475a51'80a43520_u128},
+ {Sign::NEG, -138, 0x9ff3814d'2e4a36b2'a8740b91'c95df537_u128},
+ {Sign::NEG, -138, 0x8ff5e0f2'e661e1c6'57d895d3'5921b59c_u128},
+ {Sign::NEG, -139, 0xfff00155'35588833'3c56c598'c659c2a3_u128},
+ {Sign::NEG, -139, 0xdff3c0e4'97ea4eb1'2ef8ec33'ed9d782a_u128},
+ {Sign::NEG, -139, 0xbff7008f'f5e0c257'379eba7e'6465ff63_u128},
+ {Sign::NEG, -139, 0x9ff9c053'5073a370'3f972b78'3fcab757_u128},
+ {Sign::NEG, -140, 0xfff80055'51558885'de026e27'1ee0549d_u128},
+ {Sign::NEG, -140, 0xbffb8023'febc0c25'eceb47ea'01f6c632_u128},
+ {Sign::NEG, -141, 0xfffc0015'54d55888'7333c578'57e1ed52_u128},
+ {Sign::NEG, -142, 0xfffe0005'55455588'87dde026'fa704374_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -141, 0x80010002'aab2aac4'44999abe'2fe2cc65_u128},
+ {Sign::POS, -140, 0x8002000a'aaeaac44'4eef3815'81464ccb_u128},
+ {Sign::POS, -140, 0xc0048024'01440c26'dfeb4850'85f6f454_u128},
+ {Sign::POS, -139, 0x8004002a'acaac445'99abe3be'3a1c6e93_u128},
+ {Sign::POS, -139, 0xa0064053'5a37a37a'6bc1e20e'ac8448b4_u128},
+ {Sign::POS, -139, 0xc0090090'0a20c275'979eedc0'64c242fd_u128},
+ {Sign::POS, -139, 0xe00c40e4'bd6e4efd'c72446cc'1bf728bd_u128},
+ {Sign::POS, -138, 0x800800aa'baac446e'f381b821'bbb569e5_u128},
+ {Sign::POS, -138, 0x900a20f3'19a3e273'569b26aa'a485ea5c_u128},
+ {Sign::POS, -138, 0xa00c814d'7c6a37f8'2dcf56c8'3c80b028_u128},
+ {Sign::POS, -138, 0xb00f21bb'e3e388ee'5f697682'84463b9b_u128},
+ {Sign::POS, -138, 0xc0120240'510c284c'b48ea6c0'5e2773a1_u128},
+ {Sign::POS, -138, 0xd01522dc'c4f87991'14d9d761'96d8043a_u128},
+ {Sign::POS, -138, 0xe0188393'40d4f241'e016a611'a4415d72_u128},
+ {Sign::POS, -138, 0xf01c2465'c5e61b6f'661e135f'49a47c40_u128},
+ {Sign::POS, -137, 0x801002ab'2ac4499a'be6bf0fa'435e8383_u128},
+ {Sign::POS, -137, 0x88121333'7898871e'9a31ba0c'bc030353_u128},
+ {Sign::POS, -137, 0x901443cc'cd362c9f'54b57dfe'0c4c840f_u128},
+ {Sign::POS, -137, 0x98169478'296fad41'7ad1e9c3'15328f7e_u128},
+ {Sign::POS, -137, 0xa0190536'8e2389b3'1f3f686c'f3d6be22_u128},
+ {Sign::POS, -137, 0xa81b9608'fc3c50ec'f105b66e'c4703ede_u128},
+ {Sign::POS, -137, 0xb01e46f0'74b0a0f3'610848c6'8df4d233_u128},
+ {Sign::POS, -137, 0xb7a0e9ed'7613acb0'2e0efddf'33a20464_u128},
+ {Sign::POS, -137, 0xbfa3d900'8e042ffb'c2cdb3c7'50f127b4_u128},
+ {Sign::POS, -137, 0xc7a6e82b'a36a7073'bd953378'6d3f4c49_u128},
+ {Sign::POS, -137, 0xcfaa176f'b76c8eb1'82e237c9'a4d450e3_u128},
+ {Sign::POS, -137, 0xd7ad66cd'cb3cbe14'c00b46a4'd0e3dfd0_u128},
+ {Sign::POS, -137, 0xdfb0d646'e0194584'ea999c0d'f8546710_u128},
+ {Sign::POS, -137, 0xe7b465db'f74c8032'cec6c2a9'ad974f4f_u128},
+ {Sign::POS, -137, 0xefb8158e'122cde5a'2d2045da'1570a07c_u128},
+ {Sign::POS, -137, 0xf7bbe55e'321ce603'6752e9b2'381e3edc_u128},
+ {Sign::POS, -137, 0xffbfd54d'588b33c5'3c1ed527'28e00e40_u128},
+ {Sign::POS, -136, 0x83e1f2ae'43793dc3'493b0d87'3fb9a340_u128},
+ {Sign::POS, -136, 0x87e40ac6'5f6cc4a0'29e38750'c9d26893_u128},
+ {Sign::POS, -136, 0x8be632ef'80e9a0df'aab9e832'7258ac3f_u128},
+ {Sign::POS, -136, 0x8fe86b2a'28bf51b3'28bc403d'8a5f3c63_u128},
+ {Sign::POS, -136, 0x93eab376'd7c36377'f720c1c9'7227fcdc_u128},
+ {Sign::POS, -136, 0x97ed0bd6'0ed17018'6ad9a3e3'd11b66c1_u128},
+ {Sign::POS, -136, 0x9bef7448'4ecb1f6c'edb27b79'c90b4019_u128},
+ {Sign::POS, -136, 0x9fb1c4cd'27012e19'a092a0d7'ab21722a_u128},
+ {Sign::POS, -136, 0xa3b44c65'b71c2d85'535d52f0'939a4d02_u128},
+ {Sign::POS, -136, 0xa7b6e412'cadcb3dc'90a57e11'edc1864e_u128},
+ {Sign::POS, -136, 0xabb98bd4'e33c4381'68e9c901'60031159_u128},
+ {Sign::POS, -136, 0xafbc43ac'813a6ea3'bf60594f'929adeb8_u128},
+ {Sign::POS, -136, 0xb3bf0b9a'25dcd7a2'8a421588'86775205_u128},
+ {Sign::POS, -136, 0xb7c1e39e'522f316d'1ab45417'663dee9e_u128},
+ {Sign::POS, -136, 0xbbc4cbb9'87433fe4'6c51ae3c'e1aea68a_u128},
+ {Sign::POS, -136, 0xbfc7c3ec'4630d83c'7c52ae8b'40ebabb7_u128},
+ {Sign::POS, -136, 0xc3cacc37'1015e15d'a857126f'7cfaaa67_u128},
+ {Sign::POS, -136, 0xc7cde49a'66165446'14d05662'cd29464a_u128},
+ {Sign::POS, -136, 0xcb90da16'44d29bb7'8379db06'ef3cd6bb_u128},
+ {Sign::POS, -136, 0xcf9411aa'99ddb7de'9025f4c6'7dd38bb6_u128},
+ {Sign::POS, -136, 0xd3975958'f681086d'd6f8a61c'892032ee_u128},
+ {Sign::POS, -136, 0xd79ab121'dbf8714c'9a2f20b4'e2332d47_u128},
+ {Sign::POS, -136, 0xdb9e1905'cb85ea59'3c767d61'f51d375b_u128},
+ {Sign::POS, -136, 0xdfa19105'46717fca'd4b2bd65'bb25493c_u128},
+ {Sign::POS, -136, 0xe3a51920'ce095292'c96c1254'a30ef91f_u128},
+ {Sign::POS, -136, 0xe7a8b158'e3a198be'73e324ce'0946b214_u128},
+ {Sign::POS, -136, 0xebac59ae'08949dd8'cacd125a'12bac62c_u128},
+ {Sign::POS, -136, 0xef6fd620'b2b7a503'cafdc272'27b71eaa_u128},
+ {Sign::POS, -136, 0xf3739daf'959aaafc'688d4282'f6026aa3_u128},
+ {Sign::POS, -136, 0xf777755d'03f4e0b6'e54e9e38'04464cdd_u128},
+ {Sign::POS, -136, 0xfb7b5d29'7f388a12'cb78b383'f4b59dce_u128},
+ {Sign::POS, -136, 0xff7f5515'88de024f'ee055fc5'15062c04_u128},
+ {Sign::POS, -135, 0x81c1ae90'd131de38'207812b4'3382acdd_u128},
+ {Sign::POS, -135, 0x83c3baa7'26a721cc'dc90c4c4'b61f3a87_u128},
+ {Sign::POS, -135, 0x85c5cece'05941dbc'1a03f13f'b2c978b1_u128},
+ {Sign::POS, -135, 0x87c7eb05'aec1304f'b36f282e'83a7dc36_u128},
+ {Sign::POS, -135, 0x89a9eccd'56a980c0'd82a4661'6d4c393f_u128},
+ {Sign::POS, -135, 0x8bac18a6'40185360'bc6ff847'13c9babd_u128},
+ {Sign::POS, -135, 0x8dae4c90'b22574f4'9f7942a5'16fc2d8a_u128},
+ {Sign::POS, -135, 0x8fb0888c'eda546ab'15e50cfd'9b29b427_u128},
+ {Sign::POS, -135, 0x91b2cc9b'336f3718'9f465296'ae7dd49a_u128},
+ {Sign::POS, -135, 0x93b518bb'c45dc268'b49c1eb9'b348e6e4_u128},
+ {Sign::POS, -135, 0x95b76cee'e14e728e'daa320cd'64c9d9c7_u128},
+ {Sign::POS, -135, 0x9799a333'de49b963'75a91950'ffe1e3b5_u128},
+ {Sign::POS, -135, 0x999c070b'a32068cd'5c6abcbf'43f03f14_u128},
+ {Sign::POS, -135, 0x9b9e72f6'b295ad4f'5a9e7f26'5d1ed157_u128},
+ {Sign::POS, -135, 0x9da0e6f5'4d9318fd'efeb98d0'2a195c17_u128},
+ {Sign::POS, -135, 0x9fa36307'b5054ca8'2aa503a3'110ab5a7_u128},
+ {Sign::POS, -135, 0xa1a5e72e'29dbf808'd0fe7e05'869eb825_u128},
+ {Sign::POS, -135, 0xa3884a68'a750cb10'e80a28f4'e1e500d2_u128},
+ {Sign::POS, -135, 0xa58ade36'aeef9f0b'53106415'1ca6e30b_u128},
+ {Sign::POS, -135, 0xa78d7a19'82c4b08f'27c01ffa'8e2e3c4b_u128},
+ {Sign::POS, -135, 0xa9901e11'63cbbbf5'7ba9408d'c857d568_u128},
+ {Sign::POS, -135, 0xab92ca1e'93038d76'104d1e33'31d3b4fa_u128},
+ {Sign::POS, -135, 0xad957e41'516e0158'9343c846'fcdf9137_u128},
+ {Sign::POS, -135, 0xaf780e79'b2514889'3977e89a'ec59bfa2_u128},
+ {Sign::POS, -135, 0xb17ad246'ef3713bc'913d4e3d'c55c3e6e_u128},
+ {Sign::POS, -135, 0xb37d9e2a'7a56b09d'777b52a9'e70d8bcc_u128},
+ {Sign::POS, -135, 0xb5807224'94be0c91'55de916f'd30591de_u128},
+ {Sign::POS, -135, 0xb7834e35'7f7e2600'e79cfb37'be2861e4_u128},
+ {Sign::POS, -135, 0xb986325d'7bab0c89'90983104'd3805389_u128},
+ {Sign::POS, -135, 0xbb68ef9c'254aa378'59e3b2ec'71ce64f4_u128},
+ {Sign::POS, -135, 0xbd6be371'8c77636f'e83183bf'3dd612ef_u128},
+ {Sign::POS, -135, 0xbf6edf5e'c44d9d35'c4e3b0ac'2fd52b7f_u128},
};
// Logarithm range reduction - Step 3:
@@ -660,147 +664,147 @@ constexpr double S3[139] = {
// r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
// s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
// print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
-// MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
-const Float128 LOG_R3[139] = {
- {Sign::NEG, -142, MType({0xe39d3faf42340ed7, 0x89ff6b38d5de2622})},
- {Sign::NEG, -142, MType({0x7ff3326682c02485, 0x87ff6f80ccb40f16})},
- {Sign::NEG, -142, MType({0x5caf4fbe343cf928, 0x85ff73b8c3cdf731})},
- {Sign::NEG, -142, MType({0xcdb6e554348f7fe8, 0x83ff77e0bb2ade79})},
- {Sign::NEG, -142, MType({0xef009c2457de25d, 0x81ff7bf8b2c9c4f6})},
- {Sign::NEG, -143, MType({0x8883333c57b57c74, 0xffff000155535558})},
- {Sign::NEG, -143, MType({0xf32668f39c70d183, 0xfbff07f145931f44})},
- {Sign::NEG, -143, MType({0x459a73c6a6486fe3, 0xf7ff0fc13650e7bd})},
- {Sign::NEG, -143, MType({0x37b18cca7dd3a29f, 0xf3ff1771278aaecd})},
- {Sign::NEG, -143, MType({0x513f610d21bcfc78, 0xefff1f01193e7480})},
- {Sign::NEG, -143, MType({0xea190b95c0690b7b, 0xebff26710b6a38e1})},
- {Sign::NEG, -143, MType({0x2a150f64f0ad1743, 0xe7ff2dc0fe0bfbfd})},
- {Sign::NEG, -143, MType({0x90b5174e995e9d1, 0xe3ff34f0f121bddd})},
- {Sign::NEG, -143, MType({0x4ed512b9b93ea2bf, 0xdfff3c00e4a97e8c})},
- {Sign::NEG, -143, MType({0x934cea217ab794a2, 0xdbff42f0d8a13e15})},
- {Sign::NEG, -143, MType({0x3e4ebe948afd2c76, 0xd7ff49c0cd06fc83})},
- {Sign::NEG, -143, MType({0x87b7c0f5bcfee2e1, 0xd3ff5070c1d8b9df})},
- {Sign::NEG, -143, MType({0x776666228cb6371b, 0xcfff5700b7147634})},
- {Sign::NEG, -143, MType({0xe53a60f3514db358, 0xcbff5d70acb8318b})},
- {Sign::NEG, -143, MType({0x79149c3b6e57fa86, 0xc7ff63c0a2c1ebef})},
- {Sign::NEG, -143, MType({0xaad734c98416df2a, 0xc3ff69f0992fa568})},
- {Sign::NEG, -143, MType({0xc26573679ed28334, 0xbfff70008fff5e00})},
- {Sign::NEG, -143, MType({0xd7a3c6db6540809f, 0xbbff75f0872f15c0})},
- {Sign::NEG, -143, MType({0xd277bde645fb1aad, 0xb7ff7bc07ebcccb1})},
- {Sign::NEG, -143, MType({0x6ac80145a4087793, 0xb3ff817076a682dc})},
- {Sign::NEG, -143, MType({0x287c4db30271e265, 0xafff87006eea3849})},
- {Sign::NEG, -143, MType({0x637d6de42eeb151e, 0xabff8c706785ed00})},
- {Sign::NEG, -143, MType({0x43b5348b6b898a8c, 0xa7ff91c06077a10a})},
- {Sign::NEG, -143, MType({0xc10e7657978bd7f6, 0xa3ff96f059bd546e})},
- {Sign::NEG, -143, MType({0xa37503f457310e59, 0x9fff9c0053550735})},
- {Sign::NEG, -143, MType({0x82d5a40a3aa022ff, 0x9bffa0f04d3cb966})},
- {Sign::NEG, -143, MType({0xc71e0d3ee3df5f4d, 0x97ffa5c047726b08})},
- {Sign::NEG, -143, MType({0xa83ce0352bdbd79b, 0x93ffaa7041f41c23})},
- {Sign::NEG, -143, MType({0x2e21a18d4680e8e4, 0x8fffaf003cbfccbe})},
- {Sign::NEG, -143, MType({0x30bcb3e4e5dfbd28, 0x8bffb37037d37cdf})},
- {Sign::NEG, -143, MType({0x57ff51d75c66d64a, 0x87ffb7c0332d2c8d})},
- {Sign::NEG, -143, MType({0x1bdb87fdbe299f43, 0x83ffbbf02ecadbcf})},
- {Sign::NEG, -144, MType({0x88885dde02700703, 0xffff800055551555})},
- {Sign::NEG, -144, MType({0xd259ca803a0c1870, 0xf7ff87e04d94724c})},
- {Sign::NEG, -144, MType({0xe514130851c7070a, 0xefff8f80464fce8f})},
- {Sign::NEG, -144, MType({0x30a16898f3073a64, 0xe7ff96e03f832a2a})},
- {Sign::NEG, -144, MType({0xc4ed64517b2949ce, 0xdfff9e00392a8526})},
- {Sign::NEG, -144, MType({0x51e4fb4e32cf6350, 0xd7ffa4e03341df90})},
- {Sign::NEG, -144, MType({0x277672a88350bcce, 0xcfffab802dc53971})},
- {Sign::NEG, -144, MType({0x359153772a490f06, 0xc7ffb1e028b092d3})},
- {Sign::NEG, -144, MType({0xc265ece6b481a0e, 0xbfffb80023ffebc0})},
- {Sign::NEG, -144, MType({0xdb2781c03fa132f6, 0xb7ffbde01faf4440})},
- {Sign::NEG, -144, MType({0x7287c95c845ada33, 0xafffc3801bba9c5e})},
- {Sign::NEG, -144, MType({0x423b56b1263e5a77, 0xa7ffc8e0181df421})},
- {Sign::NEG, -144, MType({0x5a3752ca4c076fa3, 0x9fffce0014d54b91})},
- {Sign::NEG, -144, MType({0x6a71e2b27eb3f573, 0x97ffd2e011dca2b6})},
- {Sign::NEG, -144, MType({0xc2e21b72cff39d8f, 0x8fffd7800f2ff997})},
- {Sign::NEG, -144, MType({0x537ff612feb7ac9e, 0x87ffdbe00ccb503c})},
- {Sign::NEG, -145, MType({0x5888873333c57c18, 0xffffc00015554d55})},
- {Sign::NEG, -145, MType({0xfa51421842311c42, 0xefffc7c01193f9d1})},
- {Sign::NEG, -145, MType({0x2c4ed6de475b942c, 0xdfffcf000e4aa5fa})},
- {Sign::NEG, -145, MType({0xce77678cbb6fcb88, 0xcfffd5c00b7151d8})},
- {Sign::NEG, -145, MType({0xc26629a679ed3b, 0xbfffdc0008fffd78})},
- {Sign::NEG, -145, MType({0x23287cb9d3072728, 0xafffe1c006eea8e1})},
- {Sign::NEG, -145, MType({0xd5a37540fd057315, 0x9fffe7000535541c})},
- {Sign::NEG, -145, MType({0xf82e21c1fce36810, 0x8fffebc003cbff32})},
- {Sign::NEG, -146, MType({0x5588887ddde02702, 0xffffe00005555455})},
- {Sign::NEG, -146, MType({0x9ac4ed72adf5b295, 0xdfffe7800392aa14})},
- {Sign::NEG, -146, MType({0xc26648066b482, 0xbfffee00023fffaf})},
- {Sign::NEG, -146, MType({0x455a3754b292c077, 0x9ffff380014d552e})},
- {Sign::NEG, -147, MType({0x5558888833333c58, 0xfffff00001555535})},
- {Sign::NEG, -147, MType({0xe000c2665736679f, 0xbffff700008ffff5})},
- {Sign::NEG, -148, MType({0x5555888885ddde02, 0xfffff80000555551})},
- {Sign::NEG, -149, MType({0xd555588888733334, 0xfffffc0000155554})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -148, MType({0xeaaaac44444eeeef, 0x80000200000aaaaa})},
- {Sign::POS, -147, MType({0xaaaac444459999ac, 0x80000400002aaaac})},
- {Sign::POS, -147, MType({0x2000c2667596679f, 0xc00009000090000a})},
- {Sign::POS, -146, MType({0xaaac44446eeef381, 0x8000080000aaaaba})},
- {Sign::POS, -146, MType({0x655a3755f81815cc, 0xa0000c80014d557c})},
- {Sign::POS, -146, MType({0xc26684c66b482, 0xc000120002400051})},
- {Sign::POS, -146, MType({0xbac4ed7c40fb07eb, 0xe00018800392ab40})},
- {Sign::POS, -145, MType({0xaac44449999abe2c, 0x8000100002aaab2a})},
- {Sign::POS, -145, MType({0x82e21d79cbb6812, 0x9000144003cc00cd})},
- {Sign::POS, -145, MType({0xd5a37569adb01dc3, 0xa00019000535568d})},
- {Sign::POS, -145, MType({0x33287d01e8c9d1d9, 0xb0001e4006eeac74})},
- {Sign::POS, -145, MType({0xc266a32679ed48, 0xc000240009000288})},
- {Sign::POS, -145, MType({0xde77685122b2764b, 0xd0002a400b7158d1})},
- {Sign::POS, -145, MType({0x2c4ed810a8063f03, 0xe00031000e4aaf5b})},
- {Sign::POS, -145, MType({0xa5143e7be891c8f, 0xf00038401194062e})},
- {Sign::POS, -144, MType({0xac4444eeef3813a1, 0x800020000aaaaeaa})},
- {Sign::POS, -144, MType({0x5b7ff7fe1339025b, 0x880024200ccb5a6e})},
- {Sign::POS, -144, MType({0x42e21e26caf39e33, 0x900028800f300668})},
- {Sign::POS, -144, MType({0xf271e66fa5554bc6, 0x98002d2011dcb29e})},
- {Sign::POS, -144, MType({0x5a3757e0615cc676, 0xa000320014d55f19})},
- {Sign::POS, -144, MType({0xca3b5d8210ca5cab, 0xa8003720181e0bde})},
- {Sign::POS, -144, MType({0xf287d25f3cb032bb, 0xb0003c801bbab8f6})},
- {Sign::POS, -144, MType({0xe3278d840be28cdb, 0xb80042201faf6669})},
- {Sign::POS, -144, MType({0xc266dfe6b482076, 0xc000480024001440})},
- {Sign::POS, -144, MType({0x3d9166de380a6d3d, 0xc8004e2028b0c282})},
- {Sign::POS, -144, MType({0xa7768b356ba61e4b, 0xd00054802dc57139})},
- {Sign::POS, -144, MType({0xd9e51a1849db73c1, 0xd8005b203342206f})},
- {Sign::POS, -144, MType({0xc4ed8a9d907eb521, 0xe0006200392ad02e})},
- {Sign::POS, -144, MType({0xb8a197dea928acd7, 0xe80069203f838080})},
- {Sign::POS, -144, MType({0x65144cf7dcc72d3b, 0xf000708046503170})},
- {Sign::POS, -144, MType({0xda5a1108890d9f6a, 0xf80078204d94e308})},
- {Sign::POS, -143, MType({0xc4445999abe2ce2c, 0x800040002aaacaaa})},
- {Sign::POS, -143, MType({0x1fdbbb4f3bffc832, 0x840044102ecb2431})},
- {Sign::POS, -143, MType({0x97ff8f39ec91b4ee, 0x88004840332d7e1d})},
- {Sign::POS, -143, MType({0x74bcfcf0b3f0a95d, 0x8c004c9037d3d876})},
- {Sign::POS, -143, MType({0x2e21f80ca6813aff, 0x900051003cc03342})},
- {Sign::POS, -143, MType({0x6c3d4629170ce87f, 0x9400559041f48e87})},
- {Sign::POS, -143, MType({0x71e84e3b80a8881, 0x98005a404772ea4d})},
- {Sign::POS, -143, MType({0x6d62fdcbdd6bec3, 0x9c005f104d3d469a})},
- {Sign::POS, -143, MType({0xa375a6b701dc77c0, 0xa00064005355a375})},
- {Sign::POS, -143, MType({0x450f331826ad6b05, 0xa400691059be00e7})},
- {Sign::POS, -143, MType({0x83b60ea8bd0aa459, 0xa8006e4060785ef6})},
- {Sign::POS, -143, MType({0x277e691469dd13f5, 0xac0073906786bdab})},
- {Sign::POS, -143, MType({0x287d6e0a0d1e25eb, 0xb00079006eeb1d0d})},
- {Sign::POS, -143, MType({0xaec94b3be9b060f5, 0xb4007e9076a77d24})},
- {Sign::POS, -143, MType({0x1279365fce280cce, 0xb80084407ebdddfa})},
- {Sign::POS, -143, MType({0xdba5732f3e83e04a, 0xbc008a1087303f95})},
- {Sign::POS, -143, MType({0xc26759679ed5b754, 0xc00090009000a200})},
- {Sign::POS, -143, MType({0xaed95aca5edb5109, 0xc400961099310543})},
- {Sign::POS, -143, MType({0xb917091d2687160f, 0xc8009c40a2c36967})},
- {Sign::POS, -143, MType({0x293d1c2a0378e75d, 0xcc00a290acb9ce76})},
- {Sign::POS, -143, MType({0x776977bf9766f5a7, 0xd000a900b7163478})},
- {Sign::POS, -143, MType({0x4bbb31b14776a18b, 0xd400af90c1da9b78})},
- {Sign::POS, -143, MType({0x7e5297d76c8564ba, 0xd800b640cd09037f})},
- {Sign::POS, -143, MType({0x1751360f8461c447, 0xdc00bd10d8a36c98})},
- {Sign::POS, -143, MType({0x4ed9dc3c63f44c41, 0xe000c400e4abd6cc})},
- {Sign::POS, -143, MType({0x8d10a4466a5894d5, 0xe400cb10f1244226})},
- {Sign::POS, -143, MType({0x6a1af81bb4e6510e, 0xe800d240fe0eaeb1})},
- {Sign::POS, -143, MType({0xae1f97b0542a677a, 0xec00d9910b6d1c77})},
- {Sign::POS, -143, MType({0x51469efe81d014cc, 0xf000e10119418b84})},
- {Sign::POS, -143, MType({0x7bb98c06d77a18b4, 0xf400e891278dfbe2})},
- {Sign::POS, -143, MType({0x85a344d0868bed17, 0xf800f04136546d9d})},
- {Sign::POS, -143, MType({0xf7301d6990e307cc, 0xfc00f8114596e0c0})},
- {Sign::POS, -142, MType({0x4446eef38140138f, 0x80008000aaabaaac})},
- {Sign::POS, -142, MType({0x10f5e43296105497, 0x82008408b2cbe5b8})},
- {Sign::POS, -142, MType({0xedbd4f83ef63f730, 0x84008820bb2d2189})},
- {Sign::POS, -142, MType({0xfeb654fd541c638e, 0x86008c48c3d05e27})},
- {Sign::POS, -142, MType({0x7ffadeb8882f7674, 0x88009080ccb69b98})},
- {Sign::POS, -142, MType({0xc5a59fd36bd44397, 0x8a0094c8d5e0d9e1})},
+// format_hex(m), "},");
+constexpr Float128 LOG_R3[139] = {
+ {Sign::NEG, -142, 0x89ff6b38'd5de2622'e39d3faf'42340ed7_u128},
+ {Sign::NEG, -142, 0x87ff6f80'ccb40f16'7ff33266'82c02485_u128},
+ {Sign::NEG, -142, 0x85ff73b8'c3cdf731'5caf4fbe'343cf928_u128},
+ {Sign::NEG, -142, 0x83ff77e0'bb2ade79'cdb6e554'348f7fe8_u128},
+ {Sign::NEG, -142, 0x81ff7bf8'b2c9c4f6'0ef009c2'457de25d_u128},
+ {Sign::NEG, -143, 0xffff0001'55535558'8883333c'57b57c74_u128},
+ {Sign::NEG, -143, 0xfbff07f1'45931f44'f32668f3'9c70d183_u128},
+ {Sign::NEG, -143, 0xf7ff0fc1'3650e7bd'459a73c6'a6486fe3_u128},
+ {Sign::NEG, -143, 0xf3ff1771'278aaecd'37b18cca'7dd3a29f_u128},
+ {Sign::NEG, -143, 0xefff1f01'193e7480'513f610d'21bcfc78_u128},
+ {Sign::NEG, -143, 0xebff2671'0b6a38e1'ea190b95'c0690b7b_u128},
+ {Sign::NEG, -143, 0xe7ff2dc0'fe0bfbfd'2a150f64'f0ad1743_u128},
+ {Sign::NEG, -143, 0xe3ff34f0'f121bddd'090b5174'e995e9d1_u128},
+ {Sign::NEG, -143, 0xdfff3c00'e4a97e8c'4ed512b9'b93ea2bf_u128},
+ {Sign::NEG, -143, 0xdbff42f0'd8a13e15'934cea21'7ab794a2_u128},
+ {Sign::NEG, -143, 0xd7ff49c0'cd06fc83'3e4ebe94'8afd2c76_u128},
+ {Sign::NEG, -143, 0xd3ff5070'c1d8b9df'87b7c0f5'bcfee2e1_u128},
+ {Sign::NEG, -143, 0xcfff5700'b7147634'77666622'8cb6371b_u128},
+ {Sign::NEG, -143, 0xcbff5d70'acb8318b'e53a60f3'514db358_u128},
+ {Sign::NEG, -143, 0xc7ff63c0'a2c1ebef'79149c3b'6e57fa86_u128},
+ {Sign::NEG, -143, 0xc3ff69f0'992fa568'aad734c9'8416df2a_u128},
+ {Sign::NEG, -143, 0xbfff7000'8fff5e00'c2657367'9ed28334_u128},
+ {Sign::NEG, -143, 0xbbff75f0'872f15c0'd7a3c6db'6540809f_u128},
+ {Sign::NEG, -143, 0xb7ff7bc0'7ebcccb1'd277bde6'45fb1aad_u128},
+ {Sign::NEG, -143, 0xb3ff8170'76a682dc'6ac80145'a4087793_u128},
+ {Sign::NEG, -143, 0xafff8700'6eea3849'287c4db3'0271e265_u128},
+ {Sign::NEG, -143, 0xabff8c70'6785ed00'637d6de4'2eeb151e_u128},
+ {Sign::NEG, -143, 0xa7ff91c0'6077a10a'43b5348b'6b898a8c_u128},
+ {Sign::NEG, -143, 0xa3ff96f0'59bd546e'c10e7657'978bd7f6_u128},
+ {Sign::NEG, -143, 0x9fff9c00'53550735'a37503f4'57310e59_u128},
+ {Sign::NEG, -143, 0x9bffa0f0'4d3cb966'82d5a40a'3aa022ff_u128},
+ {Sign::NEG, -143, 0x97ffa5c0'47726b08'c71e0d3e'e3df5f4d_u128},
+ {Sign::NEG, -143, 0x93ffaa70'41f41c23'a83ce035'2bdbd79b_u128},
+ {Sign::NEG, -143, 0x8fffaf00'3cbfccbe'2e21a18d'4680e8e4_u128},
+ {Sign::NEG, -143, 0x8bffb370'37d37cdf'30bcb3e4'e5dfbd28_u128},
+ {Sign::NEG, -143, 0x87ffb7c0'332d2c8d'57ff51d7'5c66d64a_u128},
+ {Sign::NEG, -143, 0x83ffbbf0'2ecadbcf'1bdb87fd'be299f43_u128},
+ {Sign::NEG, -144, 0xffff8000'55551555'88885dde'02700703_u128},
+ {Sign::NEG, -144, 0xf7ff87e0'4d94724c'd259ca80'3a0c1870_u128},
+ {Sign::NEG, -144, 0xefff8f80'464fce8f'e5141308'51c7070a_u128},
+ {Sign::NEG, -144, 0xe7ff96e0'3f832a2a'30a16898'f3073a64_u128},
+ {Sign::NEG, -144, 0xdfff9e00'392a8526'c4ed6451'7b2949ce_u128},
+ {Sign::NEG, -144, 0xd7ffa4e0'3341df90'51e4fb4e'32cf6350_u128},
+ {Sign::NEG, -144, 0xcfffab80'2dc53971'277672a8'8350bcce_u128},
+ {Sign::NEG, -144, 0xc7ffb1e0'28b092d3'35915377'2a490f06_u128},
+ {Sign::NEG, -144, 0xbfffb800'23ffebc0'0c265ece'6b481a0e_u128},
+ {Sign::NEG, -144, 0xb7ffbde0'1faf4440'db2781c0'3fa132f6_u128},
+ {Sign::NEG, -144, 0xafffc380'1bba9c5e'7287c95c'845ada33_u128},
+ {Sign::NEG, -144, 0xa7ffc8e0'181df421'423b56b1'263e5a77_u128},
+ {Sign::NEG, -144, 0x9fffce00'14d54b91'5a3752ca'4c076fa3_u128},
+ {Sign::NEG, -144, 0x97ffd2e0'11dca2b6'6a71e2b2'7eb3f573_u128},
+ {Sign::NEG, -144, 0x8fffd780'0f2ff997'c2e21b72'cff39d8f_u128},
+ {Sign::NEG, -144, 0x87ffdbe0'0ccb503c'537ff612'feb7ac9e_u128},
+ {Sign::NEG, -145, 0xffffc000'15554d55'58888733'33c57c18_u128},
+ {Sign::NEG, -145, 0xefffc7c0'1193f9d1'fa514218'42311c42_u128},
+ {Sign::NEG, -145, 0xdfffcf00'0e4aa5fa'2c4ed6de'475b942c_u128},
+ {Sign::NEG, -145, 0xcfffd5c0'0b7151d8'ce77678c'bb6fcb88_u128},
+ {Sign::NEG, -145, 0xbfffdc00'08fffd78'00c26629'a679ed3b_u128},
+ {Sign::NEG, -145, 0xafffe1c0'06eea8e1'23287cb9'd3072728_u128},
+ {Sign::NEG, -145, 0x9fffe700'0535541c'd5a37540'fd057315_u128},
+ {Sign::NEG, -145, 0x8fffebc0'03cbff32'f82e21c1'fce36810_u128},
+ {Sign::NEG, -146, 0xffffe000'05555455'5588887d'dde02702_u128},
+ {Sign::NEG, -146, 0xdfffe780'0392aa14'9ac4ed72'adf5b295_u128},
+ {Sign::NEG, -146, 0xbfffee00'023fffaf'000c2664'8066b482_u128},
+ {Sign::NEG, -146, 0x9ffff380'014d552e'455a3754'b292c077_u128},
+ {Sign::NEG, -147, 0xfffff000'01555535'55588888'33333c58_u128},
+ {Sign::NEG, -147, 0xbffff700'008ffff5'e000c266'5736679f_u128},
+ {Sign::NEG, -148, 0xfffff800'00555551'55558888'85ddde02_u128},
+ {Sign::NEG, -149, 0xfffffc00'00155554'd5555888'88733334_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -148, 0x80000200'000aaaaa'eaaaac44'444eeeef_u128},
+ {Sign::POS, -147, 0x80000400'002aaaac'aaaac444'459999ac_u128},
+ {Sign::POS, -147, 0xc0000900'0090000a'2000c266'7596679f_u128},
+ {Sign::POS, -146, 0x80000800'00aaaaba'aaac4444'6eeef381_u128},
+ {Sign::POS, -146, 0xa0000c80'014d557c'655a3755'f81815cc_u128},
+ {Sign::POS, -146, 0xc0001200'02400051'000c2668'4c66b482_u128},
+ {Sign::POS, -146, 0xe0001880'0392ab40'bac4ed7c'40fb07eb_u128},
+ {Sign::POS, -145, 0x80001000'02aaab2a'aac44449'999abe2c_u128},
+ {Sign::POS, -145, 0x90001440'03cc00cd'082e21d7'9cbb6812_u128},
+ {Sign::POS, -145, 0xa0001900'0535568d'd5a37569'adb01dc3_u128},
+ {Sign::POS, -145, 0xb0001e40'06eeac74'33287d01'e8c9d1d9_u128},
+ {Sign::POS, -145, 0xc0002400'09000288'00c266a3'2679ed48_u128},
+ {Sign::POS, -145, 0xd0002a40'0b7158d1'de776851'22b2764b_u128},
+ {Sign::POS, -145, 0xe0003100'0e4aaf5b'2c4ed810'a8063f03_u128},
+ {Sign::POS, -145, 0xf0003840'1194062e'0a5143e7'be891c8f_u128},
+ {Sign::POS, -144, 0x80002000'0aaaaeaa'ac4444ee'ef3813a1_u128},
+ {Sign::POS, -144, 0x88002420'0ccb5a6e'5b7ff7fe'1339025b_u128},
+ {Sign::POS, -144, 0x90002880'0f300668'42e21e26'caf39e33_u128},
+ {Sign::POS, -144, 0x98002d20'11dcb29e'f271e66f'a5554bc6_u128},
+ {Sign::POS, -144, 0xa0003200'14d55f19'5a3757e0'615cc676_u128},
+ {Sign::POS, -144, 0xa8003720'181e0bde'ca3b5d82'10ca5cab_u128},
+ {Sign::POS, -144, 0xb0003c80'1bbab8f6'f287d25f'3cb032bb_u128},
+ {Sign::POS, -144, 0xb8004220'1faf6669'e3278d84'0be28cdb_u128},
+ {Sign::POS, -144, 0xc0004800'24001440'0c266dfe'6b482076_u128},
+ {Sign::POS, -144, 0xc8004e20'28b0c282'3d9166de'380a6d3d_u128},
+ {Sign::POS, -144, 0xd0005480'2dc57139'a7768b35'6ba61e4b_u128},
+ {Sign::POS, -144, 0xd8005b20'3342206f'd9e51a18'49db73c1_u128},
+ {Sign::POS, -144, 0xe0006200'392ad02e'c4ed8a9d'907eb521_u128},
+ {Sign::POS, -144, 0xe8006920'3f838080'b8a197de'a928acd7_u128},
+ {Sign::POS, -144, 0xf0007080'46503170'65144cf7'dcc72d3b_u128},
+ {Sign::POS, -144, 0xf8007820'4d94e308'da5a1108'890d9f6a_u128},
+ {Sign::POS, -143, 0x80004000'2aaacaaa'c4445999'abe2ce2c_u128},
+ {Sign::POS, -143, 0x84004410'2ecb2431'1fdbbb4f'3bffc832_u128},
+ {Sign::POS, -143, 0x88004840'332d7e1d'97ff8f39'ec91b4ee_u128},
+ {Sign::POS, -143, 0x8c004c90'37d3d876'74bcfcf0'b3f0a95d_u128},
+ {Sign::POS, -143, 0x90005100'3cc03342'2e21f80c'a6813aff_u128},
+ {Sign::POS, -143, 0x94005590'41f48e87'6c3d4629'170ce87f_u128},
+ {Sign::POS, -143, 0x98005a40'4772ea4d'071e84e3'b80a8881_u128},
+ {Sign::POS, -143, 0x9c005f10'4d3d469a'06d62fdc'bdd6bec3_u128},
+ {Sign::POS, -143, 0xa0006400'5355a375'a375a6b7'01dc77c0_u128},
+ {Sign::POS, -143, 0xa4006910'59be00e7'450f3318'26ad6b05_u128},
+ {Sign::POS, -143, 0xa8006e40'60785ef6'83b60ea8'bd0aa459_u128},
+ {Sign::POS, -143, 0xac007390'6786bdab'277e6914'69dd13f5_u128},
+ {Sign::POS, -143, 0xb0007900'6eeb1d0d'287d6e0a'0d1e25eb_u128},
+ {Sign::POS, -143, 0xb4007e90'76a77d24'aec94b3b'e9b060f5_u128},
+ {Sign::POS, -143, 0xb8008440'7ebdddfa'1279365f'ce280cce_u128},
+ {Sign::POS, -143, 0xbc008a10'87303f95'dba5732f'3e83e04a_u128},
+ {Sign::POS, -143, 0xc0009000'9000a200'c2675967'9ed5b754_u128},
+ {Sign::POS, -143, 0xc4009610'99310543'aed95aca'5edb5109_u128},
+ {Sign::POS, -143, 0xc8009c40'a2c36967'b917091d'2687160f_u128},
+ {Sign::POS, -143, 0xcc00a290'acb9ce76'293d1c2a'0378e75d_u128},
+ {Sign::POS, -143, 0xd000a900'b7163478'776977bf'9766f5a7_u128},
+ {Sign::POS, -143, 0xd400af90'c1da9b78'4bbb31b1'4776a18b_u128},
+ {Sign::POS, -143, 0xd800b640'cd09037f'7e5297d7'6c8564ba_u128},
+ {Sign::POS, -143, 0xdc00bd10'd8a36c98'1751360f'8461c447_u128},
+ {Sign::POS, -143, 0xe000c400'e4abd6cc'4ed9dc3c'63f44c41_u128},
+ {Sign::POS, -143, 0xe400cb10'f1244226'8d10a446'6a5894d5_u128},
+ {Sign::POS, -143, 0xe800d240'fe0eaeb1'6a1af81b'b4e6510e_u128},
+ {Sign::POS, -143, 0xec00d991'0b6d1c77'ae1f97b0'542a677a_u128},
+ {Sign::POS, -143, 0xf000e101'19418b84'51469efe'81d014cc_u128},
+ {Sign::POS, -143, 0xf400e891'278dfbe2'7bb98c06'd77a18b4_u128},
+ {Sign::POS, -143, 0xf800f041'36546d9d'85a344d0'868bed17_u128},
+ {Sign::POS, -143, 0xfc00f811'4596e0c0'f7301d69'90e307cc_u128},
+ {Sign::POS, -142, 0x80008000'aaabaaac'4446eef3'8140138f_u128},
+ {Sign::POS, -142, 0x82008408'b2cbe5b8'10f5e432'96105497_u128},
+ {Sign::POS, -142, 0x84008820'bb2d2189'edbd4f83'ef63f730_u128},
+ {Sign::POS, -142, 0x86008c48'c3d05e27'feb654fd'541c638e_u128},
+ {Sign::POS, -142, 0x88009080'ccb69b98'7ffadeb8'882f7674_u128},
+ {Sign::POS, -142, 0x8a0094c8'd5e0d9e1'c5a59fd3'6bd44397_u128},
};
// Minimax polynomial generated by Sollya with:
@@ -809,11 +813,11 @@ const Float128 LOG_R3[139] = {
// > P;
// > dirtyinfnorm(log(1 + x)/x - 1 - x*P, [-0x1.01928p-22 , 0x1p-22]);
// 0x1.ce1e...p-116
-const Float128 BIG_COEFFS[4]{
- {Sign::POS, -130, MType({0x7ed78465d460315b, 0xccccccd74818e397})},
- {Sign::NEG, -129, MType({0xc6388a23871ce156, 0x80000000000478b0})},
- {Sign::POS, -129, MType({0xaa807bd867763262, 0xaaaaaaaaaaaaaaaa})},
- {Sign::NEG, -128, MType({0x0, 0x8000000000000000})},
+constexpr Float128 BIG_COEFFS[4]{
+ {Sign::POS, -130, 0xccccccd7'4818e397'7ed78465'd460315b_u128},
+ {Sign::NEG, -129, 0x80000000'000478b0'c6388a23'871ce156_u128},
+ {Sign::POS, -129, 0xaaaaaaaa'aaaaaaaa'aa807bd8'67763262_u128},
+ {Sign::NEG, -128, 0x80000000'00000000'00000000'00000000_u128},
};
LIBC_INLINE double log1p_accurate(int e_x, int index,
@@ -873,7 +877,7 @@ LIBC_INLINE double log1p_accurate(int e_x, int index,
LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
using FPBits_t = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
constexpr int EXP_BIAS = FPBits_t::EXP_BIAS;
constexpr int FRACTION_LEN = FPBits_t::FRACTION_LEN;
constexpr uint64_t FRACTION_MASK = FPBits_t::FRACTION_MASK;
diff --git a/src/math/generic/log1pf.cpp b/src/math/generic/log1pf.cpp
index 28426a88e649..e3c7d95418b1 100644
--- a/src/math/generic/log1pf.cpp
+++ b/src/math/generic/log1pf.cpp
@@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) {
case 0xbf800000U: // x = -1.0
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
- return FPBits::inf(fputil::Sign::NEG).get_val();
+ return FPBits::inf(Sign::NEG).get_val();
#ifndef LIBC_TARGET_CPU_HAS_FMA
case 0x4cc1c80bU: // x = 0x1.839016p+26f
return fputil::round_result_slightly_down(0x1.26fc04p+4f);
diff --git a/src/math/generic/log2.cpp b/src/math/generic/log2.cpp
index ab392166475c..c68bc60e8468 100644
--- a/src/math/generic/log2.cpp
+++ b/src/math/generic/log2.cpp
@@ -14,6 +14,7 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "common_constants.h"
@@ -23,8 +24,8 @@ namespace LIBC_NAMESPACE {
// 128-bit precision dyadic floating point numbers.
using Float128 = typename fputil::DyadicFloat<128>;
-using MType = typename Float128::MantissaType;
-using Sign = fputil::Sign;
+
+using LIBC_NAMESPACE::operator""_u128;
namespace {
@@ -165,144 +166,146 @@ const fputil::DoubleDouble LOG_R1[128] = {
{0.0, 0.0},
};
-const LogRR LOG2_TABLE = {
+alignas(64) constexpr LogRR LOG2_TABLE = {
// -log2(r) with 128-bit precision generated by SageMath with:
- //
+ // def format_hex(value):
+ // l = hex(value)[2:]
+ // n = 8
+ // x = [l[i:i + n] for i in range(0, len(l), n)]
+ // return "0x" + "'".join(x) + "_u128"
// for i in range(1, 127):
// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) );
// s, m, e = RealField(128)(r).log2().sign_mantissa_exponent();
- // print("{Sign::POS,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64)
- // % 2^64),
- // "})},");
+ // print("{Sign::POS,", e, ", format_hex(m), "},");
/* .step_1 = */ {
- {Sign::POS, 0, MType(0)},
- {Sign::POS, -134, MType({0xe8c251630adb856a, 0xb963dd107b993ada})},
- {Sign::POS, -133, MType({0xa41b08fbe05f82d0, 0xba1f7430f9aab1b2})},
- {Sign::POS, -132, MType({0x1f06c085bc1b865d, 0x8c25c7262b57c149})},
- {Sign::POS, -132, MType({0x2e1c07f0438ebac0, 0xbb9ca64ecac6aaef})},
- {Sign::POS, -132, MType({0xaacc0e21d6541224, 0xeb75e8f8ff5ff022})},
- {Sign::POS, -131, MType({0x31514aef39ce6303, 0x8dd9953002a4e866})},
- {Sign::POS, -131, MType({0x50799beaaab2940c, 0xa62b07f3457c4070})},
- {Sign::POS, -131, MType({0xda288fc615a727dc, 0xbeb024b67dda6339})},
- {Sign::POS, -131, MType({0x22dbbaced44516ce, 0xcb0657cd5dbe4f6f})},
- {Sign::POS, -131, MType({0xd939dceecdd9ce05, 0xe3da945b878e27d0})},
- {Sign::POS, -131, MType({0x9596a8e2e84c8f45, 0xfce4aee0e88b2749})},
- {Sign::POS, -130, MType({0x243efd9325954cfe, 0x84bf1c673032495d})},
- {Sign::POS, -130, MType({0x91d79938e7226384, 0x916d6e1559a4b696})},
- {Sign::POS, -130, MType({0x22563c9ed9462091, 0x9e37db2866f2850b})},
- {Sign::POS, -130, MType({0x3a53ca1181015ada, 0xa4a7c31dc6f9a5d5})},
- {Sign::POS, -130, MType({0x3eb8023eed65d601, 0xb19d45fa1be70855})},
- {Sign::POS, -130, MType({0xce5cabbd2d753d9b, 0xb823018e3cfc25f0})},
- {Sign::POS, -130, MType({0x54dbf16fb0695ee3, 0xc544c055fde99333})},
- {Sign::POS, -130, MType({0x5196a85a067c6739, 0xcbe0e589e3f6042d})},
- {Sign::POS, -130, MType({0xf349845e48955078, 0xd930124bea9a2c66})},
- {Sign::POS, -130, MType({0x815ef705cfaef035, 0xdfe33d3fffa66037})},
- {Sign::POS, -130, MType({0x2ba704dcaa76f41d, 0xed61169f220e97f2})},
- {Sign::POS, -130, MType({0x2062f36bc14d0d93, 0xf42be9e9b09b3def})},
- {Sign::POS, -129, MType({0x132880194144b02b, 0x80ecdde7d30ea2ed})},
- {Sign::POS, -129, MType({0x54880de63812fd49, 0x845e706cafd1bf61})},
- {Sign::POS, -129, MType({0xa87c02eaf36e2c29, 0x8b4e029b1f8ac391})},
- {Sign::POS, -129, MType({0x9804237ec8d9431d, 0x8ecc164ea93841ae})},
- {Sign::POS, -129, MType({0x20f81ca95d9e7968, 0x924e69589e6b6268})},
- {Sign::POS, -129, MType({0x124bc6f1acf95dc4, 0x995ff71b8773432d})},
- {Sign::POS, -129, MType({0x5a5e8e21bff3336b, 0x9cef470aacfb7bf9})},
- {Sign::POS, -129, MType({0x4e53fa3329f65894, 0xa08300be1f651473})},
- {Sign::POS, -129, MType({0x2742d7296a39eed6, 0xa7b7dd96762cc3c7})},
- {Sign::POS, -129, MType({0xf359c5544bc5e134, 0xab591735abc724e4})},
- {Sign::POS, -129, MType({0x6b6c874dd96e1d75, 0xaefee78f75707221})},
- {Sign::POS, -129, MType({0x21006678c0a5c390, 0xb2a95a4cc313bb59})},
- {Sign::POS, -129, MType({0x6d40900b25024b32, 0xb6587b432e47501b})},
- {Sign::POS, -129, MType({0x89e2eb553b279b3d, 0xbdc4f8167955698f})},
- {Sign::POS, -129, MType({0xd58525aad392ca50, 0xc1826c8608fe9951})},
- {Sign::POS, -129, MType({0x54dbf16fb0695ee3, 0xc544c055fde99333})},
- {Sign::POS, -129, MType({0x88d5eae3326327bb, 0xc90c004926e9dbfb})},
- {Sign::POS, -129, MType({0x46dfa05bddfded8c, 0xccd83954b6359379})},
- {Sign::POS, -129, MType({0xbfe9dbebf2e8a45e, 0xd47fcb8c0852f0c0})},
- {Sign::POS, -129, MType({0x7b11f1c5160c515c, 0xd85b3fa7a3407fa8})},
- {Sign::POS, -129, MType({0x1339e5677ec44dd0, 0xdc3be2bd8d837f7f})},
- {Sign::POS, -129, MType({0xea2b8c7bb0ee9c8b, 0xe021c2cf17ed9bdb})},
- {Sign::POS, -129, MType({0xaec562332791fe38, 0xe40cee16a2ff21c4})},
- {Sign::POS, -129, MType({0x71682ebacca79cfa, 0xe7fd7308d6895b14})},
- {Sign::POS, -129, MType({0xa5ad5ce9fb5a7bb6, 0xebf36055e1abc61e})},
- {Sign::POS, -129, MType({0x3225190531a852c5, 0xefeec4eac371584e})},
- {Sign::POS, -129, MType({0xda8ad649da21eab0, 0xf3efaff29c559a77})},
- {Sign::POS, -129, MType({0x4c3e2ea7c15c3d1e, 0xf7f630d808fc2ada})},
- {Sign::POS, -129, MType({0xbcb9bfa9852e0d35, 0xfc02574686680cc6})},
- {Sign::POS, -128, MType({0xce032f41d1e774e8, 0x800a1995f0019518})},
- {Sign::POS, -128, MType({0x9b39ffeebc29372a, 0x8215ea5cd3e4c4c7})},
- {Sign::POS, -128, MType({0x87f95f1befb6f806, 0x8424a6335c777e0b})},
- {Sign::POS, -128, MType({0xb987b42e3bb332a1, 0x8636557862acb7ce})},
- {Sign::POS, -128, MType({0x139a7ba83bf2d136, 0x884b00aef726cec5})},
- {Sign::POS, -128, MType({0x50799beaaab2941, 0x8a62b07f3457c407})},
- {Sign::POS, -128, MType({0x8bd744617e9b7d52, 0x8c7d6db7169e0cda})},
- {Sign::POS, -128, MType({0x46ad444333ceb10, 0x8e9b414b5a92a606})},
- {Sign::POS, -128, MType({0xef4c737fba4f5d66, 0x90bc345861bf3d52})},
- {Sign::POS, -128, MType({0xae441c09d761c549, 0x92e050231df57d6f})},
- {Sign::POS, -128, MType({0x6e36aa9ce90a3879, 0x95079e1a0382dc79})},
- {Sign::POS, -128, MType({0xefca1a184e93809, 0x973227d6027ebd8a})},
- {Sign::POS, -128, MType({0xefca1a184e93809, 0x973227d6027ebd8a})},
- {Sign::POS, -128, MType({0x124bc6f1acf95dc4, 0x995ff71b8773432d})},
- {Sign::POS, -128, MType({0x352bea51e58ea9e8, 0x9b9115db83a3dd2d})},
- {Sign::POS, -128, MType({0x266d6cdc959153bc, 0x9dc58e347d37696d})},
- {Sign::POS, -128, MType({0x4527d82c8214ddca, 0x9ffd6a73a78eaf35})},
- {Sign::POS, -128, MType({0x404cabb76d600e3c, 0xa238b5160413106e})},
- {Sign::POS, -128, MType({0x404cabb76d600e3c, 0xa238b5160413106e})},
- {Sign::POS, -128, MType({0xcab7d2ec23f0eef3, 0xa47778c98bcc86a1})},
- {Sign::POS, -128, MType({0x761c48dd859de2d3, 0xa6b9c06e6211646b})},
- {Sign::POS, -128, MType({0x7fd3b7d7e5d148bb, 0xa8ff971810a5e181})},
- {Sign::POS, -128, MType({0xc27c6780d92b4d11, 0xab49080ecda53208})},
- {Sign::POS, -128, MType({0xdb502402c94092cd, 0xad961ed0cb91d406})},
- {Sign::POS, -128, MType({0xdb502402c94092cd, 0xad961ed0cb91d406})},
- {Sign::POS, -128, MType({0x3432ef6b732b6843, 0xafe6e71393eeda29})},
- {Sign::POS, -128, MType({0xbb324da7e046e792, 0xb23b6cc56cc84c99})},
- {Sign::POS, -128, MType({0xb21709ce430c8e24, 0xb493bc0ec9954243})},
- {Sign::POS, -128, MType({0xb21709ce430c8e24, 0xb493bc0ec9954243})},
- {Sign::POS, -128, MType({0xe91ad16ecff10111, 0xb6efe153c7e319f6})},
- {Sign::POS, -128, MType({0xce31e481cd797e79, 0xb94fe935b83e3eb5})},
- {Sign::POS, -128, MType({0xda3e961a96c580fa, 0xbbb3e094b3d228d3})},
- {Sign::POS, -128, MType({0xda3e961a96c580fa, 0xbbb3e094b3d228d3})},
- {Sign::POS, -128, MType({0xf396598aae91499a, 0xbe1bd4913f3fda43})},
- {Sign::POS, -128, MType({0xae4cceb0f621941b, 0xc087d28dfb2febb8})},
- {Sign::POS, -128, MType({0xae4cceb0f621941b, 0xc087d28dfb2febb8})},
- {Sign::POS, -128, MType({0x6c1855c42078f81b, 0xc2f7e831632b6670})},
- {Sign::POS, -128, MType({0x169535fb8bf577c8, 0xc56c23679b4d206e})},
- {Sign::POS, -128, MType({0x169535fb8bf577c8, 0xc56c23679b4d206e})},
- {Sign::POS, -128, MType({0x3b24cecc60217942, 0xc7e492644d64237e})},
- {Sign::POS, -128, MType({0x3dc2687fcf939696, 0xca6143a49626d820})},
- {Sign::POS, -128, MType({0x3dc2687fcf939696, 0xca6143a49626d820})},
- {Sign::POS, -128, MType({0xa62e6add1a901a0, 0xcce245f1031e41fa})},
- {Sign::POS, -128, MType({0x5bb6e23138ad51e1, 0xcf67a85fa1f89a04})},
- {Sign::POS, -128, MType({0x5bb6e23138ad51e1, 0xcf67a85fa1f89a04})},
- {Sign::POS, -128, MType({0x7fc60a5103092bae, 0xd1f17a5621fb01ac})},
- {Sign::POS, -128, MType({0xbfe9dbebf2e8a45e, 0xd47fcb8c0852f0c0})},
- {Sign::POS, -128, MType({0xbfe9dbebf2e8a45e, 0xd47fcb8c0852f0c0})},
- {Sign::POS, -128, MType({0x8e2d7d378127d823, 0xd712ac0cf811659d})},
- {Sign::POS, -128, MType({0x5c1a7f14b168b365, 0xd9aa2c3b0ea3cbc1})},
- {Sign::POS, -128, MType({0x5c1a7f14b168b365, 0xd9aa2c3b0ea3cbc1})},
- {Sign::POS, -128, MType({0xb7579f0f8d3d514b, 0xdc465cd155a90942})},
- {Sign::POS, -128, MType({0xb7579f0f8d3d514b, 0xdc465cd155a90942})},
- {Sign::POS, -128, MType({0xb087205eb55aea85, 0xdee74ee64b0c38d3})},
- {Sign::POS, -128, MType({0x424a2623d60dfb16, 0xe18d13ee805a4de3})},
- {Sign::POS, -128, MType({0x424a2623d60dfb16, 0xe18d13ee805a4de3})},
- {Sign::POS, -128, MType({0x4d3a591ae6854787, 0xe437bdbf5254459c})},
- {Sign::POS, -128, MType({0x4d3a591ae6854787, 0xe437bdbf5254459c})},
- {Sign::POS, -128, MType({0x8dcdb6b24c5c5cdf, 0xe6e75e91b9cca551})},
- {Sign::POS, -128, MType({0x33ac7d9ebba8a53c, 0xe99c090536ece983})},
- {Sign::POS, -128, MType({0x33ac7d9ebba8a53c, 0xe99c090536ece983})},
- {Sign::POS, -128, MType({0xfb2eede4b59d8959, 0xec55d022d80e3d27})},
- {Sign::POS, -128, MType({0xfb2eede4b59d8959, 0xec55d022d80e3d27})},
- {Sign::POS, -128, MType({0x308b454666de8f99, 0xef14c7605d60654c})},
- {Sign::POS, -128, MType({0x308b454666de8f99, 0xef14c7605d60654c})},
- {Sign::POS, -128, MType({0x8383cb0ce23bebd4, 0xf1d902a37aaa5085})},
- {Sign::POS, -128, MType({0x8383cb0ce23bebd4, 0xf1d902a37aaa5085})},
- {Sign::POS, -128, MType({0x64fc87b4a41f7b70, 0xf4a2964538813c67})},
- {Sign::POS, -128, MType({0x64fc87b4a41f7b70, 0xf4a2964538813c67})},
- {Sign::POS, -128, MType({0x3f5d7d82b65c5686, 0xf77197157665f689})},
- {Sign::POS, -128, MType({0x3f5d7d82b65c5686, 0xf77197157665f689})},
- {Sign::POS, -128, MType({0x6476077b9fbd41ae, 0xfa461a5e8f4b759d})},
- {Sign::POS, -128, MType({0x6476077b9fbd41ae, 0xfa461a5e8f4b759d})},
- {Sign::POS, -128, MType({0xe3909ffd0d61778, 0xfd2035e9221ef5d0})},
- {Sign::POS, 0, MType(0)},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -134, 0xb963dd10'7b993ada'e8c25163'0adb856a_u128},
+ {Sign::POS, -133, 0xba1f7430'f9aab1b2'a41b08fb'e05f82d0_u128},
+ {Sign::POS, -132, 0x8c25c726'2b57c149'1f06c085'bc1b865d_u128},
+ {Sign::POS, -132, 0xbb9ca64e'cac6aaef'2e1c07f0'438ebac0_u128},
+ {Sign::POS, -132, 0xeb75e8f8'ff5ff022'aacc0e21'd6541224_u128},
+ {Sign::POS, -131, 0x8dd99530'02a4e866'31514aef'39ce6303_u128},
+ {Sign::POS, -131, 0xa62b07f3'457c4070'50799bea'aab2940c_u128},
+ {Sign::POS, -131, 0xbeb024b6'7dda6339'da288fc6'15a727dc_u128},
+ {Sign::POS, -131, 0xcb0657cd'5dbe4f6f'22dbbace'd44516ce_u128},
+ {Sign::POS, -131, 0xe3da945b'878e27d0'd939dcee'cdd9ce05_u128},
+ {Sign::POS, -131, 0xfce4aee0'e88b2749'9596a8e2'e84c8f45_u128},
+ {Sign::POS, -130, 0x84bf1c67'3032495d'243efd93'25954cfe_u128},
+ {Sign::POS, -130, 0x916d6e15'59a4b696'91d79938'e7226384_u128},
+ {Sign::POS, -130, 0x9e37db28'66f2850b'22563c9e'd9462091_u128},
+ {Sign::POS, -130, 0xa4a7c31d'c6f9a5d5'3a53ca11'81015ada_u128},
+ {Sign::POS, -130, 0xb19d45fa'1be70855'3eb8023e'ed65d601_u128},
+ {Sign::POS, -130, 0xb823018e'3cfc25f0'ce5cabbd'2d753d9b_u128},
+ {Sign::POS, -130, 0xc544c055'fde99333'54dbf16f'b0695ee3_u128},
+ {Sign::POS, -130, 0xcbe0e589'e3f6042d'5196a85a'067c6739_u128},
+ {Sign::POS, -130, 0xd930124b'ea9a2c66'f349845e'48955078_u128},
+ {Sign::POS, -130, 0xdfe33d3f'ffa66037'815ef705'cfaef035_u128},
+ {Sign::POS, -130, 0xed61169f'220e97f2'2ba704dc'aa76f41d_u128},
+ {Sign::POS, -130, 0xf42be9e9'b09b3def'2062f36b'c14d0d93_u128},
+ {Sign::POS, -129, 0x80ecdde7'd30ea2ed'13288019'4144b02b_u128},
+ {Sign::POS, -129, 0x845e706c'afd1bf61'54880de6'3812fd49_u128},
+ {Sign::POS, -129, 0x8b4e029b'1f8ac391'a87c02ea'f36e2c29_u128},
+ {Sign::POS, -129, 0x8ecc164e'a93841ae'9804237e'c8d9431d_u128},
+ {Sign::POS, -129, 0x924e6958'9e6b6268'20f81ca9'5d9e7968_u128},
+ {Sign::POS, -129, 0x995ff71b'8773432d'124bc6f1'acf95dc4_u128},
+ {Sign::POS, -129, 0x9cef470a'acfb7bf9'5a5e8e21'bff3336b_u128},
+ {Sign::POS, -129, 0xa08300be'1f651473'4e53fa33'29f65894_u128},
+ {Sign::POS, -129, 0xa7b7dd96'762cc3c7'2742d729'6a39eed6_u128},
+ {Sign::POS, -129, 0xab591735'abc724e4'f359c554'4bc5e134_u128},
+ {Sign::POS, -129, 0xaefee78f'75707221'6b6c874d'd96e1d75_u128},
+ {Sign::POS, -129, 0xb2a95a4c'c313bb59'21006678'c0a5c390_u128},
+ {Sign::POS, -129, 0xb6587b43'2e47501b'6d40900b'25024b32_u128},
+ {Sign::POS, -129, 0xbdc4f816'7955698f'89e2eb55'3b279b3d_u128},
+ {Sign::POS, -129, 0xc1826c86'08fe9951'd58525aa'd392ca50_u128},
+ {Sign::POS, -129, 0xc544c055'fde99333'54dbf16f'b0695ee3_u128},
+ {Sign::POS, -129, 0xc90c0049'26e9dbfb'88d5eae3'326327bb_u128},
+ {Sign::POS, -129, 0xccd83954'b6359379'46dfa05b'ddfded8c_u128},
+ {Sign::POS, -129, 0xd47fcb8c'0852f0c0'bfe9dbeb'f2e8a45e_u128},
+ {Sign::POS, -129, 0xd85b3fa7'a3407fa8'7b11f1c5'160c515c_u128},
+ {Sign::POS, -129, 0xdc3be2bd'8d837f7f'1339e567'7ec44dd0_u128},
+ {Sign::POS, -129, 0xe021c2cf'17ed9bdb'ea2b8c7b'b0ee9c8b_u128},
+ {Sign::POS, -129, 0xe40cee16'a2ff21c4'aec56233'2791fe38_u128},
+ {Sign::POS, -129, 0xe7fd7308'd6895b14'71682eba'cca79cfa_u128},
+ {Sign::POS, -129, 0xebf36055'e1abc61e'a5ad5ce9'fb5a7bb6_u128},
+ {Sign::POS, -129, 0xefeec4ea'c371584e'32251905'31a852c5_u128},
+ {Sign::POS, -129, 0xf3efaff2'9c559a77'da8ad649'da21eab0_u128},
+ {Sign::POS, -129, 0xf7f630d8'08fc2ada'4c3e2ea7'c15c3d1e_u128},
+ {Sign::POS, -129, 0xfc025746'86680cc6'bcb9bfa9'852e0d35_u128},
+ {Sign::POS, -128, 0x800a1995'f0019518'ce032f41'd1e774e8_u128},
+ {Sign::POS, -128, 0x8215ea5c'd3e4c4c7'9b39ffee'bc29372a_u128},
+ {Sign::POS, -128, 0x8424a633'5c777e0b'87f95f1b'efb6f806_u128},
+ {Sign::POS, -128, 0x86365578'62acb7ce'b987b42e'3bb332a1_u128},
+ {Sign::POS, -128, 0x884b00ae'f726cec5'139a7ba8'3bf2d136_u128},
+ {Sign::POS, -128, 0x8a62b07f'3457c407'050799be'aaab2941_u128},
+ {Sign::POS, -128, 0x8c7d6db7'169e0cda'8bd74461'7e9b7d52_u128},
+ {Sign::POS, -128, 0x8e9b414b'5a92a606'046ad444'333ceb10_u128},
+ {Sign::POS, -128, 0x90bc3458'61bf3d52'ef4c737f'ba4f5d66_u128},
+ {Sign::POS, -128, 0x92e05023'1df57d6f'ae441c09'd761c549_u128},
+ {Sign::POS, -128, 0x95079e1a'0382dc79'6e36aa9c'e90a3879_u128},
+ {Sign::POS, -128, 0x973227d6'027ebd8a'0efca1a1'84e93809_u128},
+ {Sign::POS, -128, 0x973227d6'027ebd8a'0efca1a1'84e93809_u128},
+ {Sign::POS, -128, 0x995ff71b'8773432d'124bc6f1'acf95dc4_u128},
+ {Sign::POS, -128, 0x9b9115db'83a3dd2d'352bea51'e58ea9e8_u128},
+ {Sign::POS, -128, 0x9dc58e34'7d37696d'266d6cdc'959153bc_u128},
+ {Sign::POS, -128, 0x9ffd6a73'a78eaf35'4527d82c'8214ddca_u128},
+ {Sign::POS, -128, 0xa238b516'0413106e'404cabb7'6d600e3c_u128},
+ {Sign::POS, -128, 0xa238b516'0413106e'404cabb7'6d600e3c_u128},
+ {Sign::POS, -128, 0xa47778c9'8bcc86a1'cab7d2ec'23f0eef3_u128},
+ {Sign::POS, -128, 0xa6b9c06e'6211646b'761c48dd'859de2d3_u128},
+ {Sign::POS, -128, 0xa8ff9718'10a5e181'7fd3b7d7'e5d148bb_u128},
+ {Sign::POS, -128, 0xab49080e'cda53208'c27c6780'd92b4d11_u128},
+ {Sign::POS, -128, 0xad961ed0'cb91d406'db502402'c94092cd_u128},
+ {Sign::POS, -128, 0xad961ed0'cb91d406'db502402'c94092cd_u128},
+ {Sign::POS, -128, 0xafe6e713'93eeda29'3432ef6b'732b6843_u128},
+ {Sign::POS, -128, 0xb23b6cc5'6cc84c99'bb324da7'e046e792_u128},
+ {Sign::POS, -128, 0xb493bc0e'c9954243'b21709ce'430c8e24_u128},
+ {Sign::POS, -128, 0xb493bc0e'c9954243'b21709ce'430c8e24_u128},
+ {Sign::POS, -128, 0xb6efe153'c7e319f6'e91ad16e'cff10111_u128},
+ {Sign::POS, -128, 0xb94fe935'b83e3eb5'ce31e481'cd797e79_u128},
+ {Sign::POS, -128, 0xbbb3e094'b3d228d3'da3e961a'96c580fa_u128},
+ {Sign::POS, -128, 0xbbb3e094'b3d228d3'da3e961a'96c580fa_u128},
+ {Sign::POS, -128, 0xbe1bd491'3f3fda43'f396598a'ae91499a_u128},
+ {Sign::POS, -128, 0xc087d28d'fb2febb8'ae4cceb0'f621941b_u128},
+ {Sign::POS, -128, 0xc087d28d'fb2febb8'ae4cceb0'f621941b_u128},
+ {Sign::POS, -128, 0xc2f7e831'632b6670'6c1855c4'2078f81b_u128},
+ {Sign::POS, -128, 0xc56c2367'9b4d206e'169535fb'8bf577c8_u128},
+ {Sign::POS, -128, 0xc56c2367'9b4d206e'169535fb'8bf577c8_u128},
+ {Sign::POS, -128, 0xc7e49264'4d64237e'3b24cecc'60217942_u128},
+ {Sign::POS, -128, 0xca6143a4'9626d820'3dc2687f'cf939696_u128},
+ {Sign::POS, -128, 0xca6143a4'9626d820'3dc2687f'cf939696_u128},
+ {Sign::POS, -128, 0xcce245f1'031e41fa'0a62e6ad'd1a901a0_u128},
+ {Sign::POS, -128, 0xcf67a85f'a1f89a04'5bb6e231'38ad51e1_u128},
+ {Sign::POS, -128, 0xcf67a85f'a1f89a04'5bb6e231'38ad51e1_u128},
+ {Sign::POS, -128, 0xd1f17a56'21fb01ac'7fc60a51'03092bae_u128},
+ {Sign::POS, -128, 0xd47fcb8c'0852f0c0'bfe9dbeb'f2e8a45e_u128},
+ {Sign::POS, -128, 0xd47fcb8c'0852f0c0'bfe9dbeb'f2e8a45e_u128},
+ {Sign::POS, -128, 0xd712ac0c'f811659d'8e2d7d37'8127d823_u128},
+ {Sign::POS, -128, 0xd9aa2c3b'0ea3cbc1'5c1a7f14'b168b365_u128},
+ {Sign::POS, -128, 0xd9aa2c3b'0ea3cbc1'5c1a7f14'b168b365_u128},
+ {Sign::POS, -128, 0xdc465cd1'55a90942'b7579f0f'8d3d514b_u128},
+ {Sign::POS, -128, 0xdc465cd1'55a90942'b7579f0f'8d3d514b_u128},
+ {Sign::POS, -128, 0xdee74ee6'4b0c38d3'b087205e'b55aea85_u128},
+ {Sign::POS, -128, 0xe18d13ee'805a4de3'424a2623'd60dfb16_u128},
+ {Sign::POS, -128, 0xe18d13ee'805a4de3'424a2623'd60dfb16_u128},
+ {Sign::POS, -128, 0xe437bdbf'5254459c'4d3a591a'e6854787_u128},
+ {Sign::POS, -128, 0xe437bdbf'5254459c'4d3a591a'e6854787_u128},
+ {Sign::POS, -128, 0xe6e75e91'b9cca551'8dcdb6b2'4c5c5cdf_u128},
+ {Sign::POS, -128, 0xe99c0905'36ece983'33ac7d9e'bba8a53c_u128},
+ {Sign::POS, -128, 0xe99c0905'36ece983'33ac7d9e'bba8a53c_u128},
+ {Sign::POS, -128, 0xec55d022'd80e3d27'fb2eede4'b59d8959_u128},
+ {Sign::POS, -128, 0xec55d022'd80e3d27'fb2eede4'b59d8959_u128},
+ {Sign::POS, -128, 0xef14c760'5d60654c'308b4546'66de8f99_u128},
+ {Sign::POS, -128, 0xef14c760'5d60654c'308b4546'66de8f99_u128},
+ {Sign::POS, -128, 0xf1d902a3'7aaa5085'8383cb0c'e23bebd4_u128},
+ {Sign::POS, -128, 0xf1d902a3'7aaa5085'8383cb0c'e23bebd4_u128},
+ {Sign::POS, -128, 0xf4a29645'38813c67'64fc87b4'a41f7b70_u128},
+ {Sign::POS, -128, 0xf4a29645'38813c67'64fc87b4'a41f7b70_u128},
+ {Sign::POS, -128, 0xf7719715'7665f689'3f5d7d82'b65c5686_u128},
+ {Sign::POS, -128, 0xf7719715'7665f689'3f5d7d82'b65c5686_u128},
+ {Sign::POS, -128, 0xfa461a5e'8f4b759d'6476077b'9fbd41ae_u128},
+ {Sign::POS, -128, 0xfa461a5e'8f4b759d'6476077b'9fbd41ae_u128},
+ {Sign::POS, -128, 0xfd2035e9'221ef5d0'0e3909ff'd0d61778_u128},
+ {Sign::POS, 0, 0_u128},
},
// -log2(r) for the second step, generated by SageMath with:
//
@@ -310,202 +313,202 @@ const LogRR LOG2_TABLE = {
// r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) );
// s, m, e = RealField(128)(r).log2().sign_mantissa_exponent();
// print("{Sign::NEG," if s == 1 else "{Sign::POS,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_2 = */
{
- {Sign::NEG, -135, MType({0xb5cfed58337e848a, 0xb906155918954401})},
- {Sign::NEG, -135, MType({0xffaf2ac1b1d20910, 0xb6264958a3c7fa2b})},
- {Sign::NEG, -135, MType({0x52521a3950ea2ed8, 0xb34671e439aa448e})},
- {Sign::NEG, -135, MType({0xf87e1abdee10fd95, 0xb0668efb7ef48ab7})},
- {Sign::NEG, -135, MType({0xfbd43bbcc24c5e43, 0xad86a09e185af0e8})},
- {Sign::NEG, -135, MType({0x2f4f5d48f9796742, 0xaaa6a6cbaa8d57ce})},
- {Sign::NEG, -135, MType({0x3477fd67c1cab6b3, 0xa7c6a183da375c3d})},
- {Sign::NEG, -135, MType({0x7b4d33eb381fe558, 0xa4e690c64c0056f0})},
- {Sign::NEG, -135, MType({0x3ce25e48cb498dea, 0xa2067492a48b5c43})},
- {Sign::NEG, -135, MType({0x70b0fcc9e4330983, 0x9f264ce888773bed})},
- {Sign::NEG, -135, MType({0xbc9e4267d3189b22, 0x9c4619c79c5e80bf})},
- {Sign::NEG, -135, MType({0x5fb3d896326615c4, 0x9965db2f84d7705f})},
- {Sign::NEG, -135, MType({0x178b58311e96d323, 0x9685911fe6740b02})},
- {Sign::NEG, -135, MType({0x6bf8b6cf73d847, 0x93a53b9865c20b2a})},
- {Sign::NEG, -135, MType({0x7019f6e64a580a02, 0x90c4da98a74ae561})},
- {Sign::NEG, -135, MType({0xcb5733cf0eb4191d, 0x8de46e204f93c7f6})},
- {Sign::NEG, -135, MType({0x56148d4fc5e415b6, 0x8b03f62f031d9ab8})},
- {Sign::NEG, -135, MType({0xfe5370f425872623, 0x882372c46664feaf})},
- {Sign::NEG, -135, MType({0x21b72a1457ee70d6, 0x8542e3e01de24ddf})},
- {Sign::NEG, -135, MType({0xabff4f89968bed0b, 0x81aa211f1e332fcf})},
- {Sign::NEG, -136, MType({0x86410a676480a5a7, 0xfd92f0cf88d75f24})},
- {Sign::NEG, -136, MType({0x44280889021970e4, 0xf7d1886b2a876289})},
- {Sign::NEG, -136, MType({0x32eb139d9812090d, 0xf21009106a42bc14})},
- {Sign::NEG, -136, MType({0xbef9dd41e8e42810, 0xec4e72be90cd2d2d})},
- {Sign::NEG, -136, MType({0x689d08ca6c7c3eb1, 0xe68cc574e6e1e5d7})},
- {Sign::NEG, -136, MType({0x1ef259a7f69821d, 0xe0cb0132b5338423})},
- {Sign::NEG, -136, MType({0xe22cea71b7bb8467, 0xdb0925f7446c13a9})},
- {Sign::NEG, -136, MType({0xe5bb27303f542fe, 0xd54733c1dd2d0d04})},
- {Sign::NEG, -136, MType({0x57453c8d5dc64ce1, 0xcf852a91c80f553f})},
- {Sign::NEG, -136, MType({0x6cc7add1fc09ef92, 0xc9c30a664da33d56})},
- {Sign::NEG, -136, MType({0xe678d7280de1c07f, 0xc400d33eb67081a7})},
- {Sign::NEG, -136, MType({0x419bbeb2239bdc39, 0xbe3e851a4af6496d})},
- {Sign::NEG, -136, MType({0xd4676d1d81755809, 0xb87c1ff853ab2631})},
- {Sign::NEG, -136, MType({0xb69dfef7ac2e2890, 0xb2b9a3d818fd1349})},
- {Sign::NEG, -136, MType({0x9f72fa0a8fccabc0, 0xacf710b8e3517548})},
- {Sign::NEG, -136, MType({0xb8bfe6a3addb988e, 0xa7346699fb051978})},
- {Sign::NEG, -136, MType({0x67862c8ec9dcd60d, 0xa171a57aa86c3551})},
- {Sign::NEG, -136, MType({0x9bd3370909e28a6, 0x9baecd5a33d265ee})},
- {Sign::NEG, -136, MType({0xa96bc611b991419b, 0x95ebde37e57aaf84})},
- {Sign::NEG, -136, MType({0xa50bb80f203f0d62, 0x9028d813059f7cdc})},
- {Sign::NEG, -136, MType({0x4d36cd474f65a317, 0x8a65baeadc729ec5})},
- {Sign::NEG, -136, MType({0x779be241ef4874a3, 0x84a286beb21d4b8c})},
- {Sign::NEG, -137, MType({0xe76a962fa65ace3, 0xfdbe771b9d803cea})},
- {Sign::NEG, -137, MType({0xd3d35627464a5267, 0xf237b2aef4e62e5a})},
- {Sign::NEG, -137, MType({0x162ef4b0e838c363, 0xe6b0c035fa8b328c})},
- {Sign::NEG, -137, MType({0x77bb10b976b3b9ca, 0xdb299faf3e7cd74f})},
- {Sign::NEG, -137, MType({0x209853cee70bc58b, 0xcfa2511950b77014})},
- {Sign::NEG, -137, MType({0x63f9b57cbaf2e58d, 0xc41ad472c12614d3})},
- {Sign::NEG, -137, MType({0x4fca1c931bd6e6d6, 0xb89329ba1fa2a0fd})},
- {Sign::NEG, -137, MType({0x26d26e434a53490a, 0xad0b50edfbf5b265})},
- {Sign::NEG, -137, MType({0xc55e079078dc86a0, 0xa1834a0ce5d6a82d})},
- {Sign::NEG, -137, MType({0xf05b9d5bd28f540b, 0x95fb15156ceba1b5})},
- {Sign::NEG, -137, MType({0x8ef87f1a11cdb727, 0x8a72b20620c97d84})},
- {Sign::NEG, -138, MType({0x9d6870114c1183cf, 0xfdd441bb21e7b069})},
- {Sign::NEG, -138, MType({0x63d514fff97e86f3, 0xe6c2c33499ba16c4})},
- {Sign::NEG, -138, MType({0x11a381901eadd883, 0xcfb0e875c7cc5929})},
- {Sign::NEG, -138, MType({0xa9d69d37bc0a5bac, 0xb89eb17bcabe1857})},
- {Sign::NEG, -138, MType({0x2dc97c9ffefd2497, 0xa18c1e43c10c6898})},
- {Sign::NEG, -138, MType({0xdcdc8afcb2ac09a, 0x8a792ecac911cf92})},
- {Sign::NEG, -139, MType({0xdd454eb3a1489470, 0xe6cbc61c020c8446})},
- {Sign::NEG, -139, MType({0x878035864d84b319, 0xb8a476150dfe4470})},
- {Sign::NEG, -139, MType({0x7ce595cc53b8342c, 0x8a7c6d7af1de7942})},
- {Sign::NEG, -140, MType({0x4710b59049899141, 0xb8a7588fd29b1baa})},
- {Sign::NEG, -141, MType({0x5957f633309d74e3, 0xb8a8c9d8be9ae994})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -141, MType({0x8268aba030b1adf6, 0xb8abac81ab576f3b})},
- {Sign::POS, -140, MType({0x1511cba2fb213a10, 0xb8ad1de1ac9ea6a5})},
- {Sign::POS, -139, MType({0x6379fb9fd9bc6235, 0x8a82eb7708262500})},
- {Sign::POS, -139, MType({0xb6fe1bf601ee27d5, 0xb8b000b8c65957cc})},
- {Sign::POS, -139, MType({0x8c6e60693a14e6d0, 0xe6ddcebbd72d3f7f})},
- {Sign::POS, -138, MType({0xe9bcfd0c62eaa2ca, 0x8a862ac30095c084})},
- {Sign::POS, -138, MType({0x73b214209a5234a7, 0xa19dca8e85918b6d})},
- {Sign::POS, -138, MType({0x347d4ca3109fe4db, 0xb8b5c6c35e142a9b})},
- {Sign::POS, -138, MType({0x37a62c48783bb066, 0xcfce1f646dca7745})},
- {Sign::POS, -138, MType({0x794b6437fb56344, 0xe6e6d4749883fbe3})},
- {Sign::POS, -138, MType({0x1cb9a45ed90318e6, 0xfdffe5f6c232f658})},
- {Sign::POS, -137, MType({0xbc118e5dbbef7dbc, 0x8a8ca9f6e7762d0f})},
- {Sign::POS, -137, MType({0xb4c0fb9535907cf8, 0x96198f2e5173e93b})},
- {Sign::POS, -137, MType({0xc051d2c5f00a9bb9, 0xa1a6a2a3113fe246})},
- {Sign::POS, -137, MType({0x553269878c1e5110, 0xad33e4569918a8d5})},
- {Sign::POS, -137, MType({0xbc906750b0ce372c, 0xb8c1544a5b4e2caf})},
- {Sign::POS, -137, MType({0x4c50eaa63be294b6, 0xc44ef27fca41bdd8})},
- {Sign::POS, -137, MType({0xb6cb28db8c065b44, 0xcfdcbef858660da1})},
- {Sign::POS, -137, MType({0x70479336830ceb05, 0xdb6ab9b5783f2fc5})},
- {Sign::POS, -137, MType({0x2a458c831f6aeb49, 0xe6f8e2b89c629b7a})},
- {Sign::POS, -137, MType({0x6489ba5bd391e206, 0xf2873a0337772c8a})},
- {Sign::POS, -137, MType({0x13f6fda510aeec3b, 0xfe15bf96bc35246b})},
- {Sign::POS, -136, MType({0x2f9a0ef9e8250836, 0x84d239ba4eb315a9})},
- {Sign::POS, -136, MType({0x389019e822b70f1e, 0x8a99aacf26f2a8a7})},
- {Sign::POS, -136, MType({0x308beeffa12cf669, 0x9061330aa04f87ae})},
- {Sign::POS, -136, MType({0x9886a71b25a2085d, 0x9628d26d7448a43f})},
- {Sign::POS, -136, MType({0x70ba9cebe0b969c3, 0x9bf088f85c65a56b})},
- {Sign::POS, -136, MType({0xcd855dc705ea2bea, 0xa1b856ac1236e85b})},
- {Sign::POS, -136, MType({0x7736196b11afb331, 0xa7803b894f5580e0})},
- {Sign::POS, -136, MType({0x94c99761b8eab3d8, 0xad483790cd6339fa})},
- {Sign::POS, -136, MType({0x6194b8c040814736, 0xb3104ac3460a9668})},
- {Sign::POS, -136, MType({0xedde8d24c7a999cc, 0xb8d8752172fed130})},
- {Sign::POS, -136, MType({0xea6b01ebde42f1d0, 0xbea0b6ac0dfbde2f})},
- {Sign::POS, -136, MType({0x7ef732b69334cf50, 0xc4690f63d0c66aa1})},
- {Sign::POS, -136, MType({0x2ba86275fcfc2d72, 0xca317f49752bddae})},
- {Sign::POS, -136, MType({0xb56ea44e185bf99f, 0xcffa065db50258f6})},
- {Sign::POS, -136, MType({0x1d5c3bbeb6902bfe, 0xd5c2a4a14a28b920})},
- {Sign::POS, -136, MType({0xa2f2bb9e156b0f37, 0xdb8b5a14ee86965f})},
- {Sign::POS, -136, MType({0xd166eb8da06ab5ef, 0xe15426b95c0c4506})},
- {Sign::POS, -136, MType({0x97dc7bae4219de0f, 0xe71d0a8f4cb2d60f})},
- {Sign::POS, -136, MType({0x6c9a8e7698f416c4, 0xece605977a7c17a8})},
- {Sign::POS, -136, MType({0x7b3a20aa5289695e, 0xf2af17d29f7295c0})},
- {Sign::POS, -136, MType({0xddcf578ee2c2897b, 0xf878414175a99a93})},
- {Sign::POS, -136, MType({0xe10ebd96c3ec30ec, 0xfe4181e4b73d2f37})},
- {Sign::POS, -135, MType({0xa9b7baecb34ba577, 0x82056cde8f290e13})},
- {Sign::POS, -135, MType({0x2da910dc61c182da, 0x8430f56d5e1edfd1})},
- {Sign::POS, -135, MType({0xfaca09dc7e0ba8b5, 0x8715b5a8f27bed90})},
- {Sign::POS, -135, MType({0xd723876173c0947, 0x89fa818019a2cace})},
- {Sign::POS, -135, MType({0x4e6651df154e8f8c, 0x8cdf58f330b64515})},
- {Sign::POS, -135, MType({0xee54b77d3bc34b6d, 0x8fc43c0294dd8af3})},
- {Sign::POS, -135, MType({0xad07dde9b5f92cce, 0x92a92aaea3442c3d})},
- {Sign::POS, -135, MType({0x261aacf944b638f0, 0x958e24f7b91a1a53})},
- {Sign::POS, -135, MType({0x232f5d64a85b219d, 0x98732ade3393a868})},
- {Sign::POS, -135, MType({0xf3a958bb706093fc, 0x9b583c626fe98bc9})},
- {Sign::POS, -135, MType({0xc9eaa059e7b0333a, 0x9e3d5984cb58dc25})},
- {Sign::POS, -135, MType({0x1e154029663243c0, 0xa1228245a32313cf})},
- {Sign::POS, -135, MType({0x16515200e283d006, 0xa407b6a5548e1006})},
- {Sign::POS, -135, MType({0xf498168a3337ca4f, 0xa6ecf6a43ce4113d})},
- {Sign::POS, -135, MType({0x8a04a89f0548a10f, 0xa9d24242b973bb63})},
- {Sign::POS, -135, MType({0xafaad01f25772805, 0xacb7998127901623})},
- {Sign::POS, -135, MType({0xc4f47950543fe0b8, 0xaf9cfc5fe4908d31})},
- {Sign::POS, -135, MType({0x338655e677d0d3ec, 0xb2826adf4dd0f08e})},
- {Sign::POS, -135, MType({0xf8ac2ce19d009541, 0xb567e4ffc0b174cc})},
- {Sign::POS, -135, MType({0x344d5e7dd7b2f465, 0xb84d6ac19a96b35c})},
- {Sign::POS, -135, MType({0xbd6a217fb4598ec7, 0xbb32fc2538e9aaca})},
- {Sign::POS, -135, MType({0xbc21ff368f562b75, 0xbe18992af917bf0e})},
- {Sign::POS, -135, MType({0x4944139ccbf2cb9a, 0xc0fe41d33892b9cc})},
- {Sign::POS, -135, MType({0x1369970c8b67e6b5, 0xc3e3f61e54d0ca9c})},
- {Sign::POS, -135, MType({0x99b370e2d04a530, 0xc6c9b60cab4c8752})},
- {Sign::POS, -135, MType({0xb81c3d48aff589f, 0xc9af819e9984ec44})},
- {Sign::POS, -135, MType({0x9f22b80993be311b, 0xcc9558d47cfd5c90})},
- {Sign::POS, -135, MType({0xac29209c8d8985ae, 0xcf7b3baeb33da265})},
- {Sign::POS, -135, MType({0x3cbb6a520292351d, 0xd2612a2d99d1ef47})},
- {Sign::POS, -135, MType({0x43de9ae40507ef24, 0xd54724518e4adc56})},
- {Sign::POS, -135, MType({0x69677b902ea4df3a, 0xd82d2a1aee3d6a97})},
- {Sign::POS, -135, MType({0xdb7a3aff74967bd5, 0xdb133b8a17430339})},
- {Sign::POS, -135, MType({0x25990c82a0066ac6, 0xddf9589f66f977de})},
- {Sign::POS, -135, MType({0xd424aacf4babf55, 0xe0df815b3b0302dd})},
- {Sign::POS, -135, MType({0xf8e3e7eb5a7bdebb, 0xe30c278d9936c595})},
- {Sign::POS, -135, MType({0x5ef8bf5adf5deebe, 0xe5f264adb62d5810})},
- {Sign::POS, -135, MType({0x331d19965368fc82, 0xe8d8ad75590bdf92})},
- {Sign::POS, -135, MType({0x901c30c427e358b8, 0xebbf01e4df85219e})},
- {Sign::POS, -135, MType({0xaeac7e9857253b06, 0xeea561fca7504dc1})},
- {Sign::POS, -135, MType({0xe2113e5893ab5b40, 0xf18bcdbd0e28fdd7})},
- {Sign::POS, -135, MType({0x9a4efc80ae977826, 0xf472452671cf3654})},
- {Sign::POS, -135, MType({0x6bf3ba8319332c9f, 0xf758c83930076689})},
- {Sign::POS, -135, MType({0x1d732d302e75018b, 0xfa3f56f5a69a68ed})},
- {Sign::POS, -135, MType({0xba179c5dbcceec01, 0xfd25f15c33558362})},
- {Sign::POS, -134, MType({0x5543f53b8ad85039, 0x80064bb69a0533c0})},
- {Sign::POS, -134, MType({0xe971a5565b93cb67, 0x8179a4948347996b})},
- {Sign::POS, -134, MType({0x5b399644ba714691, 0x82ed0348045f379d})},
- {Sign::POS, -134, MType({0x5079f1e0ec4b8496, 0x846067d14c3b8982})},
- {Sign::POS, -134, MType({0x6aba4990a32e8873, 0x85d3d23089ce40b0})},
- {Sign::POS, -134, MType({0xe16770c3a404291c, 0x87474265ec0b4548})},
- {Sign::POS, -134, MType({0x1edb7ffb1d6b3eab, 0x88bab871a1e8b61c})},
- {Sign::POS, -134, MType({0x603243e1ba7c7865, 0x8a2e3453da5ee8cd})},
- {Sign::POS, -134, MType({0x57ea5c03ea4621dd, 0x8ba1b60cc46869f6})},
- {Sign::POS, -134, MType({0xd3534cbf43bd7fd8, 0x8d153d9c8f01fd4a})},
- {Sign::POS, -134, MType({0x62c8c8075dc91cd5, 0x8e88cb03692a9dbc})},
- {Sign::POS, -134, MType({0x4bb70a5e3db7b85, 0x8ffc5e4181e37d9e})},
- {Sign::POS, -134, MType({0xd3875ba32159547a, 0x916ff757083006c7})},
- {Sign::POS, -134, MType({0x5c94c80e7a8f66b1, 0x9286adfca91ba28d})},
- {Sign::POS, -134, MType({0x52d313c47b4f91db, 0x93fa514ba0517623})},
- {Sign::POS, -134, MType({0x80829e9f3957a4c3, 0x956dfa72866fc57d})},
- {Sign::POS, -134, MType({0x1cd4917972015ae7, 0x96e1a9718a824be5})},
- {Sign::POS, -134, MType({0x1af23c29ef3032da, 0x98555e48db96fcd2})},
- {Sign::POS, -134, MType({0xe7f7bf240be67b80, 0x99c918f8a8be040e})},
- {Sign::POS, -134, MType({0x2bbe3cd4f7d868fa, 0x9b3cd9812109c5dc})},
- {Sign::POS, -134, MType({0x8c75d6a4c5ae460d, 0x9cb09fe2738edf14})},
- {Sign::POS, -134, MType({0x750fb989c9a06186, 0x9e246c1ccf642550})},
- {Sign::POS, -134, MType({0xde787e244901bdf9, 0x9f983e3063a2a709})},
- {Sign::POS, -134, MType({0x1ba3205ff729efa4, 0xa10c161d5f65abc0})},
- {Sign::POS, -134, MType({0xa864d2a038fb19cd, 0xa27ff3e3f1cab41b})},
- {Sign::POS, -134, MType({0xfb21f083a5fec56d, 0xa3f3d78449f17a11})},
- {Sign::POS, -134, MType({0x594c5552bcc377f5, 0xa567c0fe96fbf109})},
- {Sign::POS, -134, MType({0xaeb35a353fc5a503, 0xa6dbb053080e45fc})},
- {Sign::POS, -134, MType({0x67a5c05130c0f330, 0xa84fa581cc4edf9f})},
- {Sign::POS, -134, MType({0x4de5cafde1caf46f, 0xa9c3a08b12e65e81})},
- {Sign::POS, -134, MType({0x686fce3d160e88fd, 0xab37a16f0aff9d32})},
- {Sign::POS, -134, MType({0xde1375b3af6749a6, 0xacaba82de3c7b066})},
- {Sign::POS, -134, MType({0x243569048ac4affe, 0xadc2b114c632da56})},
- {Sign::POS, -134, MType({0xd6796227dcd39551, 0xaf36c21319b80ea2})},
- {Sign::POS, -134, MType({0xabc9265386172074, 0xb0aad8eccfb38d51})},
- {Sign::POS, -134, MType({0xcaac9f17896f2ce, 0xb21ef5a2175ac65e})},
- {Sign::POS, -134, MType({0x1c65a3c7f828972b, 0xb39318331fe56492})},
- {Sign::POS, -134, MType({0xabdc66446a4286d9, 0xb50740a0188d4daa})},
- {Sign::POS, -134, MType({0x2f3bbe8e8d72abec, 0xb67b6ee9308ea27b})},
- {Sign::POS, -134, MType({0xb67dbdd7f03d168c, 0xb7efa30e9727bf11})},
+ {Sign::NEG, -135, 0xb9061559'18954401'b5cfed58'337e848a_u128},
+ {Sign::NEG, -135, 0xb6264958'a3c7fa2b'ffaf2ac1'b1d20910_u128},
+ {Sign::NEG, -135, 0xb34671e4'39aa448e'52521a39'50ea2ed8_u128},
+ {Sign::NEG, -135, 0xb0668efb'7ef48ab7'f87e1abd'ee10fd95_u128},
+ {Sign::NEG, -135, 0xad86a09e'185af0e8'fbd43bbc'c24c5e43_u128},
+ {Sign::NEG, -135, 0xaaa6a6cb'aa8d57ce'2f4f5d48'f9796742_u128},
+ {Sign::NEG, -135, 0xa7c6a183'da375c3d'3477fd67'c1cab6b3_u128},
+ {Sign::NEG, -135, 0xa4e690c6'4c0056f0'7b4d33eb'381fe558_u128},
+ {Sign::NEG, -135, 0xa2067492'a48b5c43'3ce25e48'cb498dea_u128},
+ {Sign::NEG, -135, 0x9f264ce8'88773bed'70b0fcc9'e4330983_u128},
+ {Sign::NEG, -135, 0x9c4619c7'9c5e80bf'bc9e4267'd3189b22_u128},
+ {Sign::NEG, -135, 0x9965db2f'84d7705f'5fb3d896'326615c4_u128},
+ {Sign::NEG, -135, 0x9685911f'e6740b02'178b5831'1e96d323_u128},
+ {Sign::NEG, -135, 0x93a53b98'65c20b2a'006bf8b6'cf73d847_u128},
+ {Sign::NEG, -135, 0x90c4da98'a74ae561'7019f6e6'4a580a02_u128},
+ {Sign::NEG, -135, 0x8de46e20'4f93c7f6'cb5733cf'0eb4191d_u128},
+ {Sign::NEG, -135, 0x8b03f62f'031d9ab8'56148d4f'c5e415b6_u128},
+ {Sign::NEG, -135, 0x882372c4'6664feaf'fe5370f4'25872623_u128},
+ {Sign::NEG, -135, 0x8542e3e0'1de24ddf'21b72a14'57ee70d6_u128},
+ {Sign::NEG, -135, 0x81aa211f'1e332fcf'abff4f89'968bed0b_u128},
+ {Sign::NEG, -136, 0xfd92f0cf'88d75f24'86410a67'6480a5a7_u128},
+ {Sign::NEG, -136, 0xf7d1886b'2a876289'44280889'021970e4_u128},
+ {Sign::NEG, -136, 0xf2100910'6a42bc14'32eb139d'9812090d_u128},
+ {Sign::NEG, -136, 0xec4e72be'90cd2d2d'bef9dd41'e8e42810_u128},
+ {Sign::NEG, -136, 0xe68cc574'e6e1e5d7'689d08ca'6c7c3eb1_u128},
+ {Sign::NEG, -136, 0xe0cb0132'b5338423'01ef259a'7f69821d_u128},
+ {Sign::NEG, -136, 0xdb0925f7'446c13a9'e22cea71'b7bb8467_u128},
+ {Sign::NEG, -136, 0xd54733c1'dd2d0d04'0e5bb273'03f542fe_u128},
+ {Sign::NEG, -136, 0xcf852a91'c80f553f'57453c8d'5dc64ce1_u128},
+ {Sign::NEG, -136, 0xc9c30a66'4da33d56'6cc7add1'fc09ef92_u128},
+ {Sign::NEG, -136, 0xc400d33e'b67081a7'e678d728'0de1c07f_u128},
+ {Sign::NEG, -136, 0xbe3e851a'4af6496d'419bbeb2'239bdc39_u128},
+ {Sign::NEG, -136, 0xb87c1ff8'53ab2631'd4676d1d'81755809_u128},
+ {Sign::NEG, -136, 0xb2b9a3d8'18fd1349'b69dfef7'ac2e2890_u128},
+ {Sign::NEG, -136, 0xacf710b8'e3517548'9f72fa0a'8fccabc0_u128},
+ {Sign::NEG, -136, 0xa7346699'fb051978'b8bfe6a3'addb988e_u128},
+ {Sign::NEG, -136, 0xa171a57a'a86c3551'67862c8e'c9dcd60d_u128},
+ {Sign::NEG, -136, 0x9baecd5a'33d265ee'09bd3370'909e28a6_u128},
+ {Sign::NEG, -136, 0x95ebde37'e57aaf84'a96bc611'b991419b_u128},
+ {Sign::NEG, -136, 0x9028d813'059f7cdc'a50bb80f'203f0d62_u128},
+ {Sign::NEG, -136, 0x8a65baea'dc729ec5'4d36cd47'4f65a317_u128},
+ {Sign::NEG, -136, 0x84a286be'b21d4b8c'779be241'ef4874a3_u128},
+ {Sign::NEG, -137, 0xfdbe771b'9d803cea'0e76a962'fa65ace3_u128},
+ {Sign::NEG, -137, 0xf237b2ae'f4e62e5a'd3d35627'464a5267_u128},
+ {Sign::NEG, -137, 0xe6b0c035'fa8b328c'162ef4b0'e838c363_u128},
+ {Sign::NEG, -137, 0xdb299faf'3e7cd74f'77bb10b9'76b3b9ca_u128},
+ {Sign::NEG, -137, 0xcfa25119'50b77014'209853ce'e70bc58b_u128},
+ {Sign::NEG, -137, 0xc41ad472'c12614d3'63f9b57c'baf2e58d_u128},
+ {Sign::NEG, -137, 0xb89329ba'1fa2a0fd'4fca1c93'1bd6e6d6_u128},
+ {Sign::NEG, -137, 0xad0b50ed'fbf5b265'26d26e43'4a53490a_u128},
+ {Sign::NEG, -137, 0xa1834a0c'e5d6a82d'c55e0790'78dc86a0_u128},
+ {Sign::NEG, -137, 0x95fb1515'6ceba1b5'f05b9d5b'd28f540b_u128},
+ {Sign::NEG, -137, 0x8a72b206'20c97d84'8ef87f1a'11cdb727_u128},
+ {Sign::NEG, -138, 0xfdd441bb'21e7b069'9d687011'4c1183cf_u128},
+ {Sign::NEG, -138, 0xe6c2c334'99ba16c4'63d514ff'f97e86f3_u128},
+ {Sign::NEG, -138, 0xcfb0e875'c7cc5929'11a38190'1eadd883_u128},
+ {Sign::NEG, -138, 0xb89eb17b'cabe1857'a9d69d37'bc0a5bac_u128},
+ {Sign::NEG, -138, 0xa18c1e43'c10c6898'2dc97c9f'fefd2497_u128},
+ {Sign::NEG, -138, 0x8a792eca'c911cf92'0dcdc8af'cb2ac09a_u128},
+ {Sign::NEG, -139, 0xe6cbc61c'020c8446'dd454eb3'a1489470_u128},
+ {Sign::NEG, -139, 0xb8a47615'0dfe4470'87803586'4d84b319_u128},
+ {Sign::NEG, -139, 0x8a7c6d7a'f1de7942'7ce595cc'53b8342c_u128},
+ {Sign::NEG, -140, 0xb8a7588f'd29b1baa'4710b590'49899141_u128},
+ {Sign::NEG, -141, 0xb8a8c9d8'be9ae994'5957f633'309d74e3_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -141, 0xb8abac81'ab576f3b'8268aba0'30b1adf6_u128},
+ {Sign::POS, -140, 0xb8ad1de1'ac9ea6a5'1511cba2'fb213a10_u128},
+ {Sign::POS, -139, 0x8a82eb77'08262500'6379fb9f'd9bc6235_u128},
+ {Sign::POS, -139, 0xb8b000b8'c65957cc'b6fe1bf6'01ee27d5_u128},
+ {Sign::POS, -139, 0xe6ddcebb'd72d3f7f'8c6e6069'3a14e6d0_u128},
+ {Sign::POS, -138, 0x8a862ac3'0095c084'e9bcfd0c'62eaa2ca_u128},
+ {Sign::POS, -138, 0xa19dca8e'85918b6d'73b21420'9a5234a7_u128},
+ {Sign::POS, -138, 0xb8b5c6c3'5e142a9b'347d4ca3'109fe4db_u128},
+ {Sign::POS, -138, 0xcfce1f64'6dca7745'37a62c48'783bb066_u128},
+ {Sign::POS, -138, 0xe6e6d474'9883fbe3'0794b643'7fb56344_u128},
+ {Sign::POS, -138, 0xfdffe5f6'c232f658'1cb9a45e'd90318e6_u128},
+ {Sign::POS, -137, 0x8a8ca9f6'e7762d0f'bc118e5d'bbef7dbc_u128},
+ {Sign::POS, -137, 0x96198f2e'5173e93b'b4c0fb95'35907cf8_u128},
+ {Sign::POS, -137, 0xa1a6a2a3'113fe246'c051d2c5'f00a9bb9_u128},
+ {Sign::POS, -137, 0xad33e456'9918a8d5'55326987'8c1e5110_u128},
+ {Sign::POS, -137, 0xb8c1544a'5b4e2caf'bc906750'b0ce372c_u128},
+ {Sign::POS, -137, 0xc44ef27f'ca41bdd8'4c50eaa6'3be294b6_u128},
+ {Sign::POS, -137, 0xcfdcbef8'58660da1'b6cb28db'8c065b44_u128},
+ {Sign::POS, -137, 0xdb6ab9b5'783f2fc5'70479336'830ceb05_u128},
+ {Sign::POS, -137, 0xe6f8e2b8'9c629b7a'2a458c83'1f6aeb49_u128},
+ {Sign::POS, -137, 0xf2873a03'37772c8a'6489ba5b'd391e206_u128},
+ {Sign::POS, -137, 0xfe15bf96'bc35246b'13f6fda5'10aeec3b_u128},
+ {Sign::POS, -136, 0x84d239ba'4eb315a9'2f9a0ef9'e8250836_u128},
+ {Sign::POS, -136, 0x8a99aacf'26f2a8a7'389019e8'22b70f1e_u128},
+ {Sign::POS, -136, 0x9061330a'a04f87ae'308beeff'a12cf669_u128},
+ {Sign::POS, -136, 0x9628d26d'7448a43f'9886a71b'25a2085d_u128},
+ {Sign::POS, -136, 0x9bf088f8'5c65a56b'70ba9ceb'e0b969c3_u128},
+ {Sign::POS, -136, 0xa1b856ac'1236e85b'cd855dc7'05ea2bea_u128},
+ {Sign::POS, -136, 0xa7803b89'4f5580e0'7736196b'11afb331_u128},
+ {Sign::POS, -136, 0xad483790'cd6339fa'94c99761'b8eab3d8_u128},
+ {Sign::POS, -136, 0xb3104ac3'460a9668'6194b8c0'40814736_u128},
+ {Sign::POS, -136, 0xb8d87521'72fed130'edde8d24'c7a999cc_u128},
+ {Sign::POS, -136, 0xbea0b6ac'0dfbde2f'ea6b01eb'de42f1d0_u128},
+ {Sign::POS, -136, 0xc4690f63'd0c66aa1'7ef732b6'9334cf50_u128},
+ {Sign::POS, -136, 0xca317f49'752bddae'2ba86275'fcfc2d72_u128},
+ {Sign::POS, -136, 0xcffa065d'b50258f6'b56ea44e'185bf99f_u128},
+ {Sign::POS, -136, 0xd5c2a4a1'4a28b920'1d5c3bbe'b6902bfe_u128},
+ {Sign::POS, -136, 0xdb8b5a14'ee86965f'a2f2bb9e'156b0f37_u128},
+ {Sign::POS, -136, 0xe15426b9'5c0c4506'd166eb8d'a06ab5ef_u128},
+ {Sign::POS, -136, 0xe71d0a8f'4cb2d60f'97dc7bae'4219de0f_u128},
+ {Sign::POS, -136, 0xece60597'7a7c17a8'6c9a8e76'98f416c4_u128},
+ {Sign::POS, -136, 0xf2af17d2'9f7295c0'7b3a20aa'5289695e_u128},
+ {Sign::POS, -136, 0xf8784141'75a99a93'ddcf578e'e2c2897b_u128},
+ {Sign::POS, -136, 0xfe4181e4'b73d2f37'e10ebd96'c3ec30ec_u128},
+ {Sign::POS, -135, 0x82056cde'8f290e13'a9b7baec'b34ba577_u128},
+ {Sign::POS, -135, 0x8430f56d'5e1edfd1'2da910dc'61c182da_u128},
+ {Sign::POS, -135, 0x8715b5a8'f27bed90'faca09dc'7e0ba8b5_u128},
+ {Sign::POS, -135, 0x89fa8180'19a2cace'0d723876'173c0947_u128},
+ {Sign::POS, -135, 0x8cdf58f3'30b64515'4e6651df'154e8f8c_u128},
+ {Sign::POS, -135, 0x8fc43c02'94dd8af3'ee54b77d'3bc34b6d_u128},
+ {Sign::POS, -135, 0x92a92aae'a3442c3d'ad07dde9'b5f92cce_u128},
+ {Sign::POS, -135, 0x958e24f7'b91a1a53'261aacf9'44b638f0_u128},
+ {Sign::POS, -135, 0x98732ade'3393a868'232f5d64'a85b219d_u128},
+ {Sign::POS, -135, 0x9b583c62'6fe98bc9'f3a958bb'706093fc_u128},
+ {Sign::POS, -135, 0x9e3d5984'cb58dc25'c9eaa059'e7b0333a_u128},
+ {Sign::POS, -135, 0xa1228245'a32313cf'1e154029'663243c0_u128},
+ {Sign::POS, -135, 0xa407b6a5'548e1006'16515200'e283d006_u128},
+ {Sign::POS, -135, 0xa6ecf6a4'3ce4113d'f498168a'3337ca4f_u128},
+ {Sign::POS, -135, 0xa9d24242'b973bb63'8a04a89f'0548a10f_u128},
+ {Sign::POS, -135, 0xacb79981'27901623'afaad01f'25772805_u128},
+ {Sign::POS, -135, 0xaf9cfc5f'e4908d31'c4f47950'543fe0b8_u128},
+ {Sign::POS, -135, 0xb2826adf'4dd0f08e'338655e6'77d0d3ec_u128},
+ {Sign::POS, -135, 0xb567e4ff'c0b174cc'f8ac2ce1'9d009541_u128},
+ {Sign::POS, -135, 0xb84d6ac1'9a96b35c'344d5e7d'd7b2f465_u128},
+ {Sign::POS, -135, 0xbb32fc25'38e9aaca'bd6a217f'b4598ec7_u128},
+ {Sign::POS, -135, 0xbe18992a'f917bf0e'bc21ff36'8f562b75_u128},
+ {Sign::POS, -135, 0xc0fe41d3'3892b9cc'4944139c'cbf2cb9a_u128},
+ {Sign::POS, -135, 0xc3e3f61e'54d0ca9c'1369970c'8b67e6b5_u128},
+ {Sign::POS, -135, 0xc6c9b60c'ab4c8752'099b370e'2d04a530_u128},
+ {Sign::POS, -135, 0xc9af819e'9984ec44'0b81c3d4'8aff589f_u128},
+ {Sign::POS, -135, 0xcc9558d4'7cfd5c90'9f22b809'93be311b_u128},
+ {Sign::POS, -135, 0xcf7b3bae'b33da265'ac29209c'8d8985ae_u128},
+ {Sign::POS, -135, 0xd2612a2d'99d1ef47'3cbb6a52'0292351d_u128},
+ {Sign::POS, -135, 0xd5472451'8e4adc56'43de9ae4'0507ef24_u128},
+ {Sign::POS, -135, 0xd82d2a1a'ee3d6a97'69677b90'2ea4df3a_u128},
+ {Sign::POS, -135, 0xdb133b8a'17430339'db7a3aff'74967bd5_u128},
+ {Sign::POS, -135, 0xddf9589f'66f977de'25990c82'a0066ac6_u128},
+ {Sign::POS, -135, 0xe0df815b'3b0302dd'0d424aac'f4babf55_u128},
+ {Sign::POS, -135, 0xe30c278d'9936c595'f8e3e7eb'5a7bdebb_u128},
+ {Sign::POS, -135, 0xe5f264ad'b62d5810'5ef8bf5a'df5deebe_u128},
+ {Sign::POS, -135, 0xe8d8ad75'590bdf92'331d1996'5368fc82_u128},
+ {Sign::POS, -135, 0xebbf01e4'df85219e'901c30c4'27e358b8_u128},
+ {Sign::POS, -135, 0xeea561fc'a7504dc1'aeac7e98'57253b06_u128},
+ {Sign::POS, -135, 0xf18bcdbd'0e28fdd7'e2113e58'93ab5b40_u128},
+ {Sign::POS, -135, 0xf4724526'71cf3654'9a4efc80'ae977826_u128},
+ {Sign::POS, -135, 0xf758c839'30076689'6bf3ba83'19332c9f_u128},
+ {Sign::POS, -135, 0xfa3f56f5'a69a68ed'1d732d30'2e75018b_u128},
+ {Sign::POS, -135, 0xfd25f15c'33558362'ba179c5d'bcceec01_u128},
+ {Sign::POS, -134, 0x80064bb6'9a0533c0'5543f53b'8ad85039_u128},
+ {Sign::POS, -134, 0x8179a494'8347996b'e971a556'5b93cb67_u128},
+ {Sign::POS, -134, 0x82ed0348'045f379d'5b399644'ba714691_u128},
+ {Sign::POS, -134, 0x846067d1'4c3b8982'5079f1e0'ec4b8496_u128},
+ {Sign::POS, -134, 0x85d3d230'89ce40b0'6aba4990'a32e8873_u128},
+ {Sign::POS, -134, 0x87474265'ec0b4548'e16770c3'a404291c_u128},
+ {Sign::POS, -134, 0x88bab871'a1e8b61c'1edb7ffb'1d6b3eab_u128},
+ {Sign::POS, -134, 0x8a2e3453'da5ee8cd'603243e1'ba7c7865_u128},
+ {Sign::POS, -134, 0x8ba1b60c'c46869f6'57ea5c03'ea4621dd_u128},
+ {Sign::POS, -134, 0x8d153d9c'8f01fd4a'd3534cbf'43bd7fd8_u128},
+ {Sign::POS, -134, 0x8e88cb03'692a9dbc'62c8c807'5dc91cd5_u128},
+ {Sign::POS, -134, 0x8ffc5e41'81e37d9e'04bb70a5'e3db7b85_u128},
+ {Sign::POS, -134, 0x916ff757'083006c7'd3875ba3'2159547a_u128},
+ {Sign::POS, -134, 0x9286adfc'a91ba28d'5c94c80e'7a8f66b1_u128},
+ {Sign::POS, -134, 0x93fa514b'a0517623'52d313c4'7b4f91db_u128},
+ {Sign::POS, -134, 0x956dfa72'866fc57d'80829e9f'3957a4c3_u128},
+ {Sign::POS, -134, 0x96e1a971'8a824be5'1cd49179'72015ae7_u128},
+ {Sign::POS, -134, 0x98555e48'db96fcd2'1af23c29'ef3032da_u128},
+ {Sign::POS, -134, 0x99c918f8'a8be040e'e7f7bf24'0be67b80_u128},
+ {Sign::POS, -134, 0x9b3cd981'2109c5dc'2bbe3cd4'f7d868fa_u128},
+ {Sign::POS, -134, 0x9cb09fe2'738edf14'8c75d6a4'c5ae460d_u128},
+ {Sign::POS, -134, 0x9e246c1c'cf642550'750fb989'c9a06186_u128},
+ {Sign::POS, -134, 0x9f983e30'63a2a709'de787e24'4901bdf9_u128},
+ {Sign::POS, -134, 0xa10c161d'5f65abc0'1ba3205f'f729efa4_u128},
+ {Sign::POS, -134, 0xa27ff3e3'f1cab41b'a864d2a0'38fb19cd_u128},
+ {Sign::POS, -134, 0xa3f3d784'49f17a11'fb21f083'a5fec56d_u128},
+ {Sign::POS, -134, 0xa567c0fe'96fbf109'594c5552'bcc377f5_u128},
+ {Sign::POS, -134, 0xa6dbb053'080e45fc'aeb35a35'3fc5a503_u128},
+ {Sign::POS, -134, 0xa84fa581'cc4edf9f'67a5c051'30c0f330_u128},
+ {Sign::POS, -134, 0xa9c3a08b'12e65e81'4de5cafd'e1caf46f_u128},
+ {Sign::POS, -134, 0xab37a16f'0aff9d32'686fce3d'160e88fd_u128},
+ {Sign::POS, -134, 0xacaba82d'e3c7b066'de1375b3'af6749a6_u128},
+ {Sign::POS, -134, 0xadc2b114'c632da56'24356904'8ac4affe_u128},
+ {Sign::POS, -134, 0xaf36c213'19b80ea2'd6796227'dcd39551_u128},
+ {Sign::POS, -134, 0xb0aad8ec'cfb38d51'abc92653'86172074_u128},
+ {Sign::POS, -134, 0xb21ef5a2'175ac65e'0caac9f1'7896f2ce_u128},
+ {Sign::POS, -134, 0xb3931833'1fe56492'1c65a3c7'f828972b_u128},
+ {Sign::POS, -134, 0xb50740a0'188d4daa'abdc6644'6a4286d9_u128},
+ {Sign::POS, -134, 0xb67b6ee9'308ea27b'2f3bbe8e'8d72abec_u128},
+ {Sign::POS, -134, 0xb7efa30e'9727bf11'b67dbdd7'f03d168c_u128},
},
// -log2(r) for the third step, generated by SageMath with:
//
@@ -513,170 +516,170 @@ const LogRR LOG2_TABLE = {
// r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
// s, m, e = RealField(128)(r).log2().sign_mantissa_exponent();
// print("{Sign::NEG," if (s == 1) else "{Sign::POS,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_3 = */
{
- {Sign::NEG, -142, MType({0x26f2c63c0827ccbb, 0xe6d3a96b978fc16e})},
- {Sign::NEG, -142, MType({0x4b56fe667c8ec091, 0xe3f107a9fbfc50ca})},
- {Sign::NEG, -142, MType({0x647d76181aec10fc, 0xe10e65d14b937265})},
- {Sign::NEG, -142, MType({0x99e8f4d5379eca79, 0xde2bc3e18653b4f5})},
- {Sign::NEG, -142, MType({0xf07da89990c20623, 0xdb4921daac3ba730})},
- {Sign::NEG, -142, MType({0x4a8121848531851a, 0xd8667fbcbd49d7cd})},
- {Sign::NEG, -142, MType({0x679a4d854ae13619, 0xd583dd87b97cd580})},
- {Sign::NEG, -142, MType({0xe4d174072487a514, 0xd2a13b3ba0d32eff})},
- {Sign::NEG, -142, MType({0x3c90319d969b54be, 0xcfbe98d8734b7301})},
- {Sign::NEG, -142, MType({0xc6a173b09ba301e6, 0xccdbf65e30e43039})},
- {Sign::NEG, -142, MType({0xb8317428d7d8d06b, 0xc9f953ccd99bf55e})},
- {Sign::NEG, -142, MType({0x23cdb51bcc2061cd, 0xc716b1246d715125})},
- {Sign::NEG, -142, MType({0xf964fc78084fd515, 0xc4340e64ec62d241})},
- {Sign::NEG, -142, MType({0x6474fb15ccbb015, 0xc1516b8e566f076a})},
- {Sign::NEG, -142, MType({0xf525ef6d0b75b1c3, 0xbe6ec8a0ab947f51})},
- {Sign::NEG, -142, MType({0x4e13532df7ee8da7, 0xbb8c259bebd1c8ae})},
- {Sign::NEG, -142, MType({0x76832500d72a9027, 0xb8a9828017257233})},
- {Sign::NEG, -142, MType({0xb14a3d285e592ba0, 0xb5c6df4d2d8e0a95})},
- {Sign::NEG, -142, MType({0x1e9e9dc9711f6e20, 0xb2e43c032f0a2089})},
- {Sign::NEG, -142, MType({0xbc176e974f255fac, 0xb00198a21b9842c1})},
- {Sign::NEG, -142, MType({0x64acf87fc0f648e6, 0xad1ef529f336fff3})},
- {Sign::NEG, -142, MType({0xd0b8a1574433e1f8, 0xaa3c519ab5e4e6d1})},
- {Sign::NEG, -142, MType({0x95f4e785371c69a9, 0xa759adf463a08610})},
- {Sign::NEG, -142, MType({0x277d5db00363a46f, 0xa4770a36fc686c63})},
- {Sign::NEG, -142, MType({0xd5cea669485ec36c, 0xa1946662803b287c})},
- {Sign::NEG, -142, MType({0xcec66fda04833322, 0x9eb1c276ef174910})},
- {Sign::NEG, -142, MType({0x1da36f6ebe3851db, 0x9bcf1e7448fb5cd2})},
- {Sign::NEG, -142, MType({0xab055d83abfc0d82, 0x98ec7a5a8de5f273})},
- {Sign::NEG, -142, MType({0x3cecf110dbda68e9, 0x9609d629bdd598a8})},
- {Sign::NEG, -142, MType({0x76bbdb565a37e84b, 0x932731e1d8c8de22})},
- {Sign::NEG, -142, MType({0xd934c38857eee4f3, 0x90448d82debe5194})},
- {Sign::NEG, -142, MType({0xc27b427b4fbfc7db, 0x8d61e90ccfb481b1})},
- {Sign::NEG, -142, MType({0x6e13de502b142b39, 0x8a7f447faba9fd2b})},
- {Sign::NEG, -142, MType({0xf4e406206614e2ba, 0x879c9fdb729d52b3})},
- {Sign::NEG, -142, MType({0x4d320daa3312ea6c, 0x84b9fb20248d10fd})},
- {Sign::NEG, -142, MType({0x4aa528fc9d433c1a, 0x81d7564dc177c6b9})},
- {Sign::NEG, -143, MType({0x3c8ad047559b1622, 0xfde962c892b80533})},
- {Sign::NEG, -143, MType({0xacf765a8fc5bcc31, 0xf82418c77870a69f})},
- {Sign::NEG, -143, MType({0xbe238832edd27f20, 0xf25ece9834168f1a})},
- {Sign::NEG, -143, MType({0x2644bfca329b708, 0xec99843ac5a6dc07})},
- {Sign::NEG, -143, MType({0xc6d05a788e614744, 0xe6d439af2d1eaac6})},
- {Sign::NEG, -143, MType({0x133fe9cc57a8c1d0, 0xe10eeef56a7b18bc})},
- {Sign::NEG, -143, MType({0xaa4cb429195fb5dd, 0xdb49a40d7db94348})},
- {Sign::NEG, -143, MType({0x951ef239abbb959, 0xd58458f766d647ce})},
- {Sign::NEG, -143, MType({0x686c430c89143d35, 0xcfbf0db325cf43ad})},
- {Sign::NEG, -143, MType({0xba79c248afd42c12, 0xc9f9c240baa15447})},
- {Sign::NEG, -143, MType({0xad19e0a92f115327, 0xc43476a0254996fd})},
- {Sign::NEG, -143, MType({0xa8ad6ac3b0c99520, 0xbe6f2ad165c5292f})},
- {Sign::NEG, -143, MType({0xd0567d4a9cc5e6a1, 0xb8a9ded47c11283d})},
- {Sign::NEG, -143, MType({0x1f87c654b231443, 0xb2e492a9682ab188})},
- {Sign::NEG, -143, MType({0xd6380b08358051bc, 0xad1f46502a0ee26d})},
- {Sign::NEG, -143, MType({0xa07b024d26d391f6, 0xa759f9c8c1bad84e})},
- {Sign::NEG, -143, MType({0x6ee868cb69e3a7d8, 0xa194ad132f2bb089})},
- {Sign::NEG, -143, MType({0xa6869eff6682f73, 0x9bcf602f725e887d})},
- {Sign::NEG, -143, MType({0xf6a44d559ccf3f61, 0x960a131d8b507d87})},
- {Sign::NEG, -143, MType({0x72066e1d30a8e210, 0x9044c5dd79fead08})},
- {Sign::NEG, -143, MType({0x75ba3245b1b856af, 0x8a7f786f3e66345c})},
- {Sign::NEG, -143, MType({0xb5ac020473ab198f, 0x84ba2ad2d88430e1})},
- {Sign::NEG, -144, MType({0x41127e3a88eb6741, 0xfde9ba1090ab7feb})},
- {Sign::NEG, -144, MType({0xbf80787522aca1c4, 0xf25f1e1f1baffdea})},
- {Sign::NEG, -144, MType({0xaf00688b14fa3adc, 0xe6d481d15210167b})},
- {Sign::NEG, -144, MType({0x4d72837c8ab4d1e5, 0xdb49e52733c60457})},
- {Sign::NEG, -144, MType({0x4e38ac27bb252090, 0xcfbf4820c0cc0236})},
- {Sign::NEG, -144, MType({0xda3661f9292f59e8, 0xc434aabdf91c4ad0})},
- {Sign::NEG, -144, MType({0x8fd0af9bdfd21488, 0xb8aa0cfedcb118de})},
- {Sign::NEG, -144, MType({0x82ee19a9abf0bfa5, 0xad1f6ee36b84a716})},
- {Sign::NEG, -144, MType({0x3cf68d5b5369a251, 0xa194d06ba591302f})},
- {Sign::NEG, -144, MType({0xbcd34f38c977647e, 0x960a31978ad0eede})},
- {Sign::NEG, -144, MType({0x76eee9c9605e2143, 0x8a7f92671b3e1dda})},
- {Sign::NEG, -145, MType({0xaa6a3887f0c803ab, 0xfde9e5b4ada5efae})},
- {Sign::NEG, -145, MType({0x6e25927e582ac191, 0xe6d4a5e27b136f13})},
- {Sign::NEG, -145, MType({0xe2ebcac2f3a8e9eb, 0xcfbf65579eb92f4a})},
- {Sign::NEG, -145, MType({0x9d9acc22d5690751, 0xb8aa2414188ba5bb})},
- {Sign::NEG, -145, MType({0x1e12604b6d4132ef, 0xa194e217e87f47cb})},
- {Sign::NEG, -145, MType({0xcf340d2acb9b92a9, 0x8a7f9f630e888add})},
- {Sign::NEG, -146, MType({0xdc5e49fbde3c520, 0xe6d4b7eb1537c8ae})},
- {Sign::NEG, -146, MType({0xc074c9557c01188, 0xb8aa2f9eb95b9332})},
- {Sign::NEG, -146, MType({0xf0f82818ff9b654f, 0x8a7fa5e109656009})},
- {Sign::NEG, -147, MType({0xd4cd612078bbe9b0, 0xb8aa35640a7c33eb})},
- {Sign::NEG, -148, MType({0xf08cf68f42e09fa0, 0xb8aa3846b33aaecf})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -148, MType({0x68bd0facdf0ddaaf, 0xb8aa3e0c0513f9b1})},
- {Sign::POS, -147, MType({0x192af653dd41575b, 0xb8aa40eeae2ec9b3})},
- {Sign::POS, -146, MType({0x3b5c89842e540a51, 0x8a7fb2dd018e4892})},
- {Sign::POS, -146, MType({0x34ad8ebdd8b2750c, 0xb8aa46b400c0bee3})},
- {Sign::POS, -146, MType({0x70b12bd698e5be74, 0xe6d4dbfc54c5dd1b})},
- {Sign::POS, -145, MType({0x8c7e424efbd90e1, 0x8a7fb95afeda5c46})},
- {Sign::POS, -145, MType({0x31b8eba774a1de77, 0xa19505707dd23344})},
- {Sign::POS, -145, MType({0xee400e8c68838733, 0xb8aa523ea755fe32})},
- {Sign::POS, -145, MType({0xe71fa0b5603bc2f, 0xcfbf9fc57b7147be})},
- {Sign::POS, -145, MType({0x7763c919d8ac65f1, 0xe6d4ee04fa2f9a92})},
- {Sign::POS, -145, MType({0x232b270bb6046ec1, 0xfdea3cfd239c815e})},
- {Sign::POS, -144, MType({0x106f39197e068972, 0x8a7fc656fbe1c368})},
- {Sign::POS, -144, MType({0x4a4a6f4012941bd9, 0x960a6e8bbb581acc})},
- {Sign::POS, -144, MType({0x5bb34c1120b3e54b, 0xa195171cd0370c34})},
- {Sign::POS, -144, MType({0x6bb6731392a3147a, 0xad1fc00a3a845cf9})},
- {Sign::POS, -144, MType({0x2be1268dcee3c8fc, 0xb8aa6953fa45d275})},
- {Sign::POS, -144, MType({0xd84158d5d50251a9, 0xc43512fa0f813201})},
- {Sign::POS, -144, MType({0x3765bda15d0ef0fa, 0xcfbfbcfc7a3c40fa})},
- {Sign::POS, -144, MType({0x9a5ddb55f9cc27d9, 0xdb4a675b3a7cc4b9})},
- {Sign::POS, -144, MType({0xdcba1c593d918775, 0xe6d512165048829b})},
- {Sign::POS, -144, MType({0x648be060e1e30a95, 0xf25fbd2dbba53ffd})},
- {Sign::POS, -144, MType({0x22658dc2f1bcf6e8, 0xfdea68a17c98c23b})},
- {Sign::POS, -143, MType({0x48ad5162fb4a236e, 0x84ba8a38c9946759})},
- {Sign::POS, -143, MType({0xdb7fe3789405ce3a, 0x8a7fe04effad9560})},
- {Sign::POS, -143, MType({0x91b56e2e4f2e5ed8, 0x90453693609acde3})},
- {Sign::POS, -143, MType({0xf8998880c3bb4d76, 0x960a8d05ec5ef390})},
- {Sign::POS, -143, MType({0xe2b878052f67efee, 0x9bcfe3a6a2fce918})},
- {Sign::POS, -143, MType({0x67df399193f707c0, 0xa1953a758477912b})},
- {Sign::POS, -143, MType({0xe51b89e4d5d095e1, 0xa75a917290d1ce78})},
- {Sign::POS, -143, MType({0xfcbbee4edbf9f47d, 0xad1fe89dc80e83b1})},
- {Sign::POS, -143, MType({0x964fbd58b168371b, 0xb2e53ff72a309387})},
- {Sign::POS, -143, MType({0xdea7276ca7acd135, 0xb8aa977eb73ae0aa})},
- {Sign::POS, -143, MType({0x47d33f7e7afc83a6, 0xbe6fef346f304dcd})},
- {Sign::POS, -143, MType({0x892603b377909123, 0xc43547185213bda0})},
- {Sign::POS, -143, MType({0x9f32660aa06239fb, 0xc9fa9f2a5fe812d6})},
- {Sign::POS, -143, MType({0xcbcc5504d7407f6c, 0xcfbff76a98b03021})},
- {Sign::POS, -143, MType({0x9608c44d06402ebe, 0xd5854fd8fc6ef834})},
- {Sign::POS, -143, MType({0xca3db5604a863477, 0xdb4aa8758b274dc1})},
- {Sign::POS, -143, MType({0x7a024036206c37d6, 0xe110014044dc137c})},
- {Sign::POS, -143, MType({0xfc2e9be890ff7ee3, 0xe6d55a3929902c17})},
- {Sign::POS, -143, MType({0xecdc275c60da1b53, 0xec9ab36039467a47})},
- {Sign::POS, -143, MType({0x2d6571e94056607f, 0xf2600cb57401e0c0})},
- {Sign::POS, -143, MType({0xe4664401fd1ca2a7, 0xf8256638d9c54234})},
- {Sign::POS, -143, MType({0x7dbba7dcb50b3fd7, 0xfdeabfea6a93815a})},
- {Sign::POS, -142, MType({0xd541f90d853c794b, 0x81d80ce51337c072})},
- {Sign::POS, -142, MType({0xb08f65392ce8b75b, 0x84bab9ec06ae11c5})},
- {Sign::POS, -142, MType({0x6e969a29f8462436, 0x879d670a0fae2600})},
- {Sign::POS, -142, MType({0xcfc8cbcaa2bf130c, 0x8a80143f2e396e7d})},
- {Sign::POS, -142, MType({0xb737e48c19421e68, 0x8d62c18b62515c98})},
- {Sign::POS, -142, MType({0x2a9689b997c50c0b, 0x90456eeeabf761ac})},
- {Sign::POS, -142, MType({0x52381fccc774d66b, 0x93281c690b2cef13})},
- {Sign::POS, -142, MType({0x7910cec1dd92dc10, 0x960ac9fa7ff37629})},
- {Sign::POS, -142, MType({0xcb5866bbaff34cb, 0x98ed77a30a4c684a})},
- {Sign::POS, -142, MType({0x9d5c02c80c702d11, 0x9bd02562aa3936d0})},
- {Sign::POS, -142, MType({0xdddad0536b56e775, 0x9eb2d3395fbb5318})},
- {Sign::POS, -142, MType({0xa3a9505d7f71247a, 0xa19581272ad42e7e})},
- {Sign::POS, -142, MType({0xe6dfbd5d210830d7, 0xa4782f2c0b853a5d})},
- {Sign::POS, -142, MType({0xc2372f447bdcfa45, 0xa75add4801cfe812})},
- {Sign::POS, -142, MType({0x73099fd532c14b05, 0xaa3d8b7b0db5a8f9})},
- {Sign::POS, -142, MType({0x5951eef483de2c37, 0xad2039c52f37ee6e})},
- {Sign::POS, -142, MType({0xf7abe6ff6da76f1e, 0xb002e826665829cd})},
- {Sign::POS, -142, MType({0xf354411ed47c5d7b, 0xb2e5969eb317cc74})},
- {Sign::POS, -142, MType({0x1428a99ba8f5911f, 0xb5c8452e157847c0})},
- {Sign::POS, -142, MType({0x44a7c4330edff2c8, 0xb8aaf3d48d7b0d0c})},
- {Sign::POS, -142, MType({0x91f1306a84e4e07b, 0xbb8da2921b218db6})},
- {Sign::POS, -142, MType({0x2bc58de40cdf7b6a, 0xbe705166be6d3b1c})},
- {Sign::POS, -142, MType({0x648680b254df1d99, 0xc1530052775f869a})},
- {Sign::POS, -142, MType({0xb136b5ace0d6f74d, 0xc435af5545f9e18e})},
- {Sign::POS, -142, MType({0xa979e6c434fad480, 0xc7185e6f2a3dbd56})},
- {Sign::POS, -142, MType({0x794df5600c90a5a, 0xc9fb0da0242c8b50})},
- {Sign::POS, -142, MType({0xa86d80814ac18cf1, 0xccddbce833c7bcd8})},
- {Sign::POS, -142, MType({0x8b8ac57a9cca2d56, 0xcfc06c475910c34e})},
- {Sign::POS, -142, MType({0xd314c7e03140001f, 0xd2a31bbd9409100f})},
- {Sign::POS, -142, MType({0xc3d4c40e20b5ec89, 0xd585cb4ae4b2147a})},
- {Sign::POS, -142, MType({0xc5351d729060644e, 0xd8687aef4b0d41ed})},
- {Sign::POS, -142, MType({0x614162e1e12e445d, 0xdb4b2aaac71c09c7})},
- {Sign::POS, -142, MType({0x44a652eadf8ede85, 0xde2dda7d58dfdd66})},
- {Sign::POS, -142, MType({0x3eb1e02af3e52c3c, 0xe1108a67005a2e29})},
- {Sign::POS, -142, MType({0x415335a253a82aa2, 0xe3f33a67bd8c6d6f})},
- {Sign::POS, -142, MType({0x611abb0833305fe1, 0xe6d5ea7f90780c97})},
+ {Sign::NEG, -142, 0xe6d3a96b'978fc16e'26f2c63c'0827ccbb_u128},
+ {Sign::NEG, -142, 0xe3f107a9'fbfc50ca'4b56fe66'7c8ec091_u128},
+ {Sign::NEG, -142, 0xe10e65d1'4b937265'647d7618'1aec10fc_u128},
+ {Sign::NEG, -142, 0xde2bc3e1'8653b4f5'99e8f4d5'379eca79_u128},
+ {Sign::NEG, -142, 0xdb4921da'ac3ba730'f07da899'90c20623_u128},
+ {Sign::NEG, -142, 0xd8667fbc'bd49d7cd'4a812184'8531851a_u128},
+ {Sign::NEG, -142, 0xd583dd87'b97cd580'679a4d85'4ae13619_u128},
+ {Sign::NEG, -142, 0xd2a13b3b'a0d32eff'e4d17407'2487a514_u128},
+ {Sign::NEG, -142, 0xcfbe98d8'734b7301'3c90319d'969b54be_u128},
+ {Sign::NEG, -142, 0xccdbf65e'30e43039'c6a173b0'9ba301e6_u128},
+ {Sign::NEG, -142, 0xc9f953cc'd99bf55e'b8317428'd7d8d06b_u128},
+ {Sign::NEG, -142, 0xc716b124'6d715125'23cdb51b'cc2061cd_u128},
+ {Sign::NEG, -142, 0xc4340e64'ec62d241'f964fc78'084fd515_u128},
+ {Sign::NEG, -142, 0xc1516b8e'566f076a'06474fb1'5ccbb015_u128},
+ {Sign::NEG, -142, 0xbe6ec8a0'ab947f51'f525ef6d'0b75b1c3_u128},
+ {Sign::NEG, -142, 0xbb8c259b'ebd1c8ae'4e13532d'f7ee8da7_u128},
+ {Sign::NEG, -142, 0xb8a98280'17257233'76832500'd72a9027_u128},
+ {Sign::NEG, -142, 0xb5c6df4d'2d8e0a95'b14a3d28'5e592ba0_u128},
+ {Sign::NEG, -142, 0xb2e43c03'2f0a2089'1e9e9dc9'711f6e20_u128},
+ {Sign::NEG, -142, 0xb00198a2'1b9842c1'bc176e97'4f255fac_u128},
+ {Sign::NEG, -142, 0xad1ef529'f336fff3'64acf87f'c0f648e6_u128},
+ {Sign::NEG, -142, 0xaa3c519a'b5e4e6d1'd0b8a157'4433e1f8_u128},
+ {Sign::NEG, -142, 0xa759adf4'63a08610'95f4e785'371c69a9_u128},
+ {Sign::NEG, -142, 0xa4770a36'fc686c63'277d5db0'0363a46f_u128},
+ {Sign::NEG, -142, 0xa1946662'803b287c'd5cea669'485ec36c_u128},
+ {Sign::NEG, -142, 0x9eb1c276'ef174910'cec66fda'04833322_u128},
+ {Sign::NEG, -142, 0x9bcf1e74'48fb5cd2'1da36f6e'be3851db_u128},
+ {Sign::NEG, -142, 0x98ec7a5a'8de5f273'ab055d83'abfc0d82_u128},
+ {Sign::NEG, -142, 0x9609d629'bdd598a8'3cecf110'dbda68e9_u128},
+ {Sign::NEG, -142, 0x932731e1'd8c8de22'76bbdb56'5a37e84b_u128},
+ {Sign::NEG, -142, 0x90448d82'debe5194'd934c388'57eee4f3_u128},
+ {Sign::NEG, -142, 0x8d61e90c'cfb481b1'c27b427b'4fbfc7db_u128},
+ {Sign::NEG, -142, 0x8a7f447f'aba9fd2b'6e13de50'2b142b39_u128},
+ {Sign::NEG, -142, 0x879c9fdb'729d52b3'f4e40620'6614e2ba_u128},
+ {Sign::NEG, -142, 0x84b9fb20'248d10fd'4d320daa'3312ea6c_u128},
+ {Sign::NEG, -142, 0x81d7564d'c177c6b9'4aa528fc'9d433c1a_u128},
+ {Sign::NEG, -143, 0xfde962c8'92b80533'3c8ad047'559b1622_u128},
+ {Sign::NEG, -143, 0xf82418c7'7870a69f'acf765a8'fc5bcc31_u128},
+ {Sign::NEG, -143, 0xf25ece98'34168f1a'be238832'edd27f20_u128},
+ {Sign::NEG, -143, 0xec99843a'c5a6dc07'02644bfc'a329b708_u128},
+ {Sign::NEG, -143, 0xe6d439af'2d1eaac6'c6d05a78'8e614744_u128},
+ {Sign::NEG, -143, 0xe10eeef5'6a7b18bc'133fe9cc'57a8c1d0_u128},
+ {Sign::NEG, -143, 0xdb49a40d'7db94348'aa4cb429'195fb5dd_u128},
+ {Sign::NEG, -143, 0xd58458f7'66d647ce'0951ef23'9abbb959_u128},
+ {Sign::NEG, -143, 0xcfbf0db3'25cf43ad'686c430c'89143d35_u128},
+ {Sign::NEG, -143, 0xc9f9c240'baa15447'ba79c248'afd42c12_u128},
+ {Sign::NEG, -143, 0xc43476a0'254996fd'ad19e0a9'2f115327_u128},
+ {Sign::NEG, -143, 0xbe6f2ad1'65c5292f'a8ad6ac3'b0c99520_u128},
+ {Sign::NEG, -143, 0xb8a9ded4'7c11283d'd0567d4a'9cc5e6a1_u128},
+ {Sign::NEG, -143, 0xb2e492a9'682ab188'01f87c65'4b231443_u128},
+ {Sign::NEG, -143, 0xad1f4650'2a0ee26d'd6380b08'358051bc_u128},
+ {Sign::NEG, -143, 0xa759f9c8'c1bad84e'a07b024d'26d391f6_u128},
+ {Sign::NEG, -143, 0xa194ad13'2f2bb089'6ee868cb'69e3a7d8_u128},
+ {Sign::NEG, -143, 0x9bcf602f'725e887d'0a6869ef'f6682f73_u128},
+ {Sign::NEG, -143, 0x960a131d'8b507d87'f6a44d55'9ccf3f61_u128},
+ {Sign::NEG, -143, 0x9044c5dd'79fead08'72066e1d'30a8e210_u128},
+ {Sign::NEG, -143, 0x8a7f786f'3e66345c'75ba3245'b1b856af_u128},
+ {Sign::NEG, -143, 0x84ba2ad2'd88430e1'b5ac0204'73ab198f_u128},
+ {Sign::NEG, -144, 0xfde9ba10'90ab7feb'41127e3a'88eb6741_u128},
+ {Sign::NEG, -144, 0xf25f1e1f'1baffdea'bf807875'22aca1c4_u128},
+ {Sign::NEG, -144, 0xe6d481d1'5210167b'af00688b'14fa3adc_u128},
+ {Sign::NEG, -144, 0xdb49e527'33c60457'4d72837c'8ab4d1e5_u128},
+ {Sign::NEG, -144, 0xcfbf4820'c0cc0236'4e38ac27'bb252090_u128},
+ {Sign::NEG, -144, 0xc434aabd'f91c4ad0'da3661f9'292f59e8_u128},
+ {Sign::NEG, -144, 0xb8aa0cfe'dcb118de'8fd0af9b'dfd21488_u128},
+ {Sign::NEG, -144, 0xad1f6ee3'6b84a716'82ee19a9'abf0bfa5_u128},
+ {Sign::NEG, -144, 0xa194d06b'a591302f'3cf68d5b'5369a251_u128},
+ {Sign::NEG, -144, 0x960a3197'8ad0eede'bcd34f38'c977647e_u128},
+ {Sign::NEG, -144, 0x8a7f9267'1b3e1dda'76eee9c9'605e2143_u128},
+ {Sign::NEG, -145, 0xfde9e5b4'ada5efae'aa6a3887'f0c803ab_u128},
+ {Sign::NEG, -145, 0xe6d4a5e2'7b136f13'6e25927e'582ac191_u128},
+ {Sign::NEG, -145, 0xcfbf6557'9eb92f4a'e2ebcac2'f3a8e9eb_u128},
+ {Sign::NEG, -145, 0xb8aa2414'188ba5bb'9d9acc22'd5690751_u128},
+ {Sign::NEG, -145, 0xa194e217'e87f47cb'1e12604b'6d4132ef_u128},
+ {Sign::NEG, -145, 0x8a7f9f63'0e888add'cf340d2a'cb9b92a9_u128},
+ {Sign::NEG, -146, 0xe6d4b7eb'1537c8ae'0dc5e49f'bde3c520_u128},
+ {Sign::NEG, -146, 0xb8aa2f9e'b95b9332'0c074c95'57c01188_u128},
+ {Sign::NEG, -146, 0x8a7fa5e1'09656009'f0f82818'ff9b654f_u128},
+ {Sign::NEG, -147, 0xb8aa3564'0a7c33eb'd4cd6120'78bbe9b0_u128},
+ {Sign::NEG, -148, 0xb8aa3846'b33aaecf'f08cf68f'42e09fa0_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -148, 0xb8aa3e0c'0513f9b1'68bd0fac'df0ddaaf_u128},
+ {Sign::POS, -147, 0xb8aa40ee'ae2ec9b3'192af653'dd41575b_u128},
+ {Sign::POS, -146, 0x8a7fb2dd'018e4892'3b5c8984'2e540a51_u128},
+ {Sign::POS, -146, 0xb8aa46b4'00c0bee3'34ad8ebd'd8b2750c_u128},
+ {Sign::POS, -146, 0xe6d4dbfc'54c5dd1b'70b12bd6'98e5be74_u128},
+ {Sign::POS, -145, 0x8a7fb95a'feda5c46'08c7e424'efbd90e1_u128},
+ {Sign::POS, -145, 0xa1950570'7dd23344'31b8eba7'74a1de77_u128},
+ {Sign::POS, -145, 0xb8aa523e'a755fe32'ee400e8c'68838733_u128},
+ {Sign::POS, -145, 0xcfbf9fc5'7b7147be'0e71fa0b'5603bc2f_u128},
+ {Sign::POS, -145, 0xe6d4ee04'fa2f9a92'7763c919'd8ac65f1_u128},
+ {Sign::POS, -145, 0xfdea3cfd'239c815e'232b270b'b6046ec1_u128},
+ {Sign::POS, -144, 0x8a7fc656'fbe1c368'106f3919'7e068972_u128},
+ {Sign::POS, -144, 0x960a6e8b'bb581acc'4a4a6f40'12941bd9_u128},
+ {Sign::POS, -144, 0xa195171c'd0370c34'5bb34c11'20b3e54b_u128},
+ {Sign::POS, -144, 0xad1fc00a'3a845cf9'6bb67313'92a3147a_u128},
+ {Sign::POS, -144, 0xb8aa6953'fa45d275'2be1268d'cee3c8fc_u128},
+ {Sign::POS, -144, 0xc43512fa'0f813201'd84158d5'd50251a9_u128},
+ {Sign::POS, -144, 0xcfbfbcfc'7a3c40fa'3765bda1'5d0ef0fa_u128},
+ {Sign::POS, -144, 0xdb4a675b'3a7cc4b9'9a5ddb55'f9cc27d9_u128},
+ {Sign::POS, -144, 0xe6d51216'5048829b'dcba1c59'3d918775_u128},
+ {Sign::POS, -144, 0xf25fbd2d'bba53ffd'648be060'e1e30a95_u128},
+ {Sign::POS, -144, 0xfdea68a1'7c98c23b'22658dc2'f1bcf6e8_u128},
+ {Sign::POS, -143, 0x84ba8a38'c9946759'48ad5162'fb4a236e_u128},
+ {Sign::POS, -143, 0x8a7fe04e'ffad9560'db7fe378'9405ce3a_u128},
+ {Sign::POS, -143, 0x90453693'609acde3'91b56e2e'4f2e5ed8_u128},
+ {Sign::POS, -143, 0x960a8d05'ec5ef390'f8998880'c3bb4d76_u128},
+ {Sign::POS, -143, 0x9bcfe3a6'a2fce918'e2b87805'2f67efee_u128},
+ {Sign::POS, -143, 0xa1953a75'8477912b'67df3991'93f707c0_u128},
+ {Sign::POS, -143, 0xa75a9172'90d1ce78'e51b89e4'd5d095e1_u128},
+ {Sign::POS, -143, 0xad1fe89d'c80e83b1'fcbbee4e'dbf9f47d_u128},
+ {Sign::POS, -143, 0xb2e53ff7'2a309387'964fbd58'b168371b_u128},
+ {Sign::POS, -143, 0xb8aa977e'b73ae0aa'dea7276c'a7acd135_u128},
+ {Sign::POS, -143, 0xbe6fef34'6f304dcd'47d33f7e'7afc83a6_u128},
+ {Sign::POS, -143, 0xc4354718'5213bda0'892603b3'77909123_u128},
+ {Sign::POS, -143, 0xc9fa9f2a'5fe812d6'9f32660a'a06239fb_u128},
+ {Sign::POS, -143, 0xcfbff76a'98b03021'cbcc5504'd7407f6c_u128},
+ {Sign::POS, -143, 0xd5854fd8'fc6ef834'9608c44d'06402ebe_u128},
+ {Sign::POS, -143, 0xdb4aa875'8b274dc1'ca3db560'4a863477_u128},
+ {Sign::POS, -143, 0xe1100140'44dc137c'7a024036'206c37d6_u128},
+ {Sign::POS, -143, 0xe6d55a39'29902c17'fc2e9be8'90ff7ee3_u128},
+ {Sign::POS, -143, 0xec9ab360'39467a47'ecdc275c'60da1b53_u128},
+ {Sign::POS, -143, 0xf2600cb5'7401e0c0'2d6571e9'4056607f_u128},
+ {Sign::POS, -143, 0xf8256638'd9c54234'e4664401'fd1ca2a7_u128},
+ {Sign::POS, -143, 0xfdeabfea'6a93815a'7dbba7dc'b50b3fd7_u128},
+ {Sign::POS, -142, 0x81d80ce5'1337c072'd541f90d'853c794b_u128},
+ {Sign::POS, -142, 0x84bab9ec'06ae11c5'b08f6539'2ce8b75b_u128},
+ {Sign::POS, -142, 0x879d670a'0fae2600'6e969a29'f8462436_u128},
+ {Sign::POS, -142, 0x8a80143f'2e396e7d'cfc8cbca'a2bf130c_u128},
+ {Sign::POS, -142, 0x8d62c18b'62515c98'b737e48c'19421e68_u128},
+ {Sign::POS, -142, 0x90456eee'abf761ac'2a9689b9'97c50c0b_u128},
+ {Sign::POS, -142, 0x93281c69'0b2cef13'52381fcc'c774d66b_u128},
+ {Sign::POS, -142, 0x960ac9fa'7ff37629'7910cec1'dd92dc10_u128},
+ {Sign::POS, -142, 0x98ed77a3'0a4c684a'0cb5866b'baff34cb_u128},
+ {Sign::POS, -142, 0x9bd02562'aa3936d0'9d5c02c8'0c702d11_u128},
+ {Sign::POS, -142, 0x9eb2d339'5fbb5318'dddad053'6b56e775_u128},
+ {Sign::POS, -142, 0xa1958127'2ad42e7e'a3a9505d'7f71247a_u128},
+ {Sign::POS, -142, 0xa4782f2c'0b853a5d'e6dfbd5d'210830d7_u128},
+ {Sign::POS, -142, 0xa75add48'01cfe812'c2372f44'7bdcfa45_u128},
+ {Sign::POS, -142, 0xaa3d8b7b'0db5a8f9'73099fd5'32c14b05_u128},
+ {Sign::POS, -142, 0xad2039c5'2f37ee6e'5951eef4'83de2c37_u128},
+ {Sign::POS, -142, 0xb002e826'665829cd'f7abe6ff'6da76f1e_u128},
+ {Sign::POS, -142, 0xb2e5969e'b317cc74'f354411e'd47c5d7b_u128},
+ {Sign::POS, -142, 0xb5c8452e'157847c0'1428a99b'a8f5911f_u128},
+ {Sign::POS, -142, 0xb8aaf3d4'8d7b0d0c'44a7c433'0edff2c8_u128},
+ {Sign::POS, -142, 0xbb8da292'1b218db6'91f1306a'84e4e07b_u128},
+ {Sign::POS, -142, 0xbe705166'be6d3b1c'2bc58de4'0cdf7b6a_u128},
+ {Sign::POS, -142, 0xc1530052'775f869a'648680b2'54df1d99_u128},
+ {Sign::POS, -142, 0xc435af55'45f9e18e'b136b5ac'e0d6f74d_u128},
+ {Sign::POS, -142, 0xc7185e6f'2a3dbd56'a979e6c4'34fad480_u128},
+ {Sign::POS, -142, 0xc9fb0da0'242c8b50'0794df56'00c90a5a_u128},
+ {Sign::POS, -142, 0xccddbce8'33c7bcd8'a86d8081'4ac18cf1_u128},
+ {Sign::POS, -142, 0xcfc06c47'5910c34e'8b8ac57a'9cca2d56_u128},
+ {Sign::POS, -142, 0xd2a31bbd'9409100f'd314c7e0'3140001f_u128},
+ {Sign::POS, -142, 0xd585cb4a'e4b2147a'c3d4c40e'20b5ec89_u128},
+ {Sign::POS, -142, 0xd8687aef'4b0d41ed'c5351d72'9060644e_u128},
+ {Sign::POS, -142, 0xdb4b2aaa'c71c09c7'614162e1'e12e445d_u128},
+ {Sign::POS, -142, 0xde2dda7d'58dfdd66'44a652ea'df8ede85_u128},
+ {Sign::POS, -142, 0xe1108a67'005a2e29'3eb1e02a'f3e52c3c_u128},
+ {Sign::POS, -142, 0xe3f33a67'bd8c6d6f'415335a2'53a82aa2_u128},
+ {Sign::POS, -142, 0xe6d5ea7f'90780c97'611abb08'33305fe1_u128},
},
// -log2(r) for the fourth step, generated by SageMath with:
//
@@ -684,150 +687,150 @@ const LogRR LOG2_TABLE = {
// r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) );
// s, m, e = RealField(128)(r).log2().sign_mantissa_exponent();
// print("{Sign::NEG," if (s == 1) else "{Sign::POS,", e, ",
- // MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
+ // format_hex(m), "},");
/* .step_4 = */
{
- {Sign::NEG, -149, MType({0xef1bffe565ce0a46, 0xbb8ce2990b5d0b90})},
- {Sign::NEG, -149, MType({0xbea3244560ca3d99, 0xb8aa39b807a576e4})},
- {Sign::NEG, -149, MType({0x8b91f71ceefa31a2, 0xb5c790d6d5c354df})},
- {Sign::NEG, -149, MType({0x9096e3d684001c0e, 0xb2e4e7f575b6a57b})},
- {Sign::NEG, -149, MType({0x86054c794367f36, 0xb0023f13e77f68b3})},
- {Sign::NEG, -149, MType({0x2d9cb33094afe4de, 0xad1f96322b1d9e80})},
- {Sign::NEG, -149, MType({0x3afa673cfb3698f3, 0xaa3ced50409146dd})},
- {Sign::NEG, -149, MType({0x6b27d8033e4c6450, 0xa75a446e27da61c4})},
- {Sign::NEG, -149, MType({0xf8d36b84d52a477b, 0xa4779b8be0f8ef2f})},
- {Sign::NEG, -149, MType({0x1eab86ae37c03565, 0xa194f2a96becef1a})},
- {Sign::NEG, -149, MType({0x175e8d56deb4ce2c, 0x9eb249c6c8b6617d})},
- {Sign::NEG, -149, MType({0x1d9ae241436519da, 0x9bcfa0e3f7554653})},
- {Sign::NEG, -149, MType({0x6c0ee71adfe44325, 0x98ecf800f7c99d96})},
- {Sign::NEG, -149, MType({0x3d68fc7c2efb522f, 0x960a4f1dca136741})},
- {Sign::NEG, -149, MType({0xcc5781e8ac28e749, 0x9327a63a6e32a34d})},
- {Sign::NEG, -149, MType({0x5388d5ced3a0f5af, 0x9044fd56e42751b6})},
- {Sign::NEG, -149, MType({0xdab5588224c7e4a, 0x8d6254732bf17275})},
- {Sign::NEG, -149, MType({0x356d5d5915c94a70, 0x8a7fab8f45910584})},
- {Sign::NEG, -149, MType({0x57d48712c69a6a7, 0x879d02ab31060ade})},
- {Sign::NEG, -149, MType({0xb88970eae5341d60, 0x84ba59c6ee50827c})},
- {Sign::NEG, -149, MType({0x89402fcbbfe331bb, 0x81d7b0e27d706c5a})},
- {Sign::NEG, -150, MType({0x649fba0879ca348b, 0xfdea0ffbbccb90e3})},
- {Sign::NEG, -150, MType({0xdccd9edfbab6f777, 0xf824be3222612d78})},
- {Sign::NEG, -150, MType({0xf066b9aa4636478e, 0xf25f6c682ba1ae69})},
- {Sign::NEG, -150, MType({0x14c7b3cb21578781, 0xec9a1a9dd88d13ab})},
- {Sign::NEG, -150, MType({0xbf4d347b528f56e1, 0xe6d4c8d329235d30})},
- {Sign::NEG, -150, MType({0x6553e0c9e1b70799, 0xe10f77081d648aef})},
- {Sign::NEG, -150, MType({0x7c385b9bd80c1375, 0xdb4a253cb5509cdb})},
- {Sign::NEG, -150, MType({0x795745ac402f919d, 0xd584d370f0e792e9})},
- {Sign::NEG, -150, MType({0xd20d3d8c2625ac1b, 0xcfbf81a4d0296d0d})},
- {Sign::NEG, -150, MType({0xfbb6dfa297551554, 0xc9fa2fd853162b3c})},
- {Sign::NEG, -150, MType({0x6bb0c62ca2867d91, 0xc434de0b79adcd6b})},
- {Sign::NEG, -150, MType({0x9757893d57e40877, 0xbe6f8c3e43f0538d})},
- {Sign::NEG, -150, MType({0xf407bebdc8f8c28e, 0xb8aa3a70b1ddbd97})},
- {Sign::NEG, -150, MType({0xf71dfa6d08b016be, 0xb2e4e8a2c3760b7e})},
- {Sign::NEG, -150, MType({0x15f6cde02b5543ce, 0xad1f96d478b93d37})},
- {Sign::NEG, -150, MType({0xc5eec8824692d1e9, 0xa75a4505d1a752b4})},
- {Sign::NEG, -150, MType({0x7c6277947172081a, 0xa194f336ce404bec})},
- {Sign::NEG, -150, MType({0xaeae662dc45a61ce, 0x9bcfa1676e8428d2})},
- {Sign::NEG, -150, MType({0xd22f1d3b59110455, 0x960a4f97b272e95b})},
- {Sign::NEG, -150, MType({0x5c4123804ab83462, 0x9044fdc79a0c8d7c})},
- {Sign::NEG, -150, MType({0xc240fd95b5cecb89, 0x8a7fabf725511528})},
- {Sign::NEG, -150, MType({0x798b2deab82fadc4, 0x84ba5a2654408055})},
- {Sign::NEG, -151, MType({0xeef86988e2227ddb, 0xfdea10aa4db59ded})},
- {Sign::NEG, -151, MType({0x62e1207c0209b090, 0xf25f6d073a400203})},
- {Sign::NEG, -151, MType({0x3989789113ec7bee, 0xe6d4c9636e202cd4})},
- {Sign::NEG, -151, MType({0x5daa65565e562909, 0xdb4a25bee9561e49})},
- {Sign::NEG, -151, MType({0xb9fcd6062a84acbd, 0xcfbf8219abe1d64b})},
- {Sign::NEG, -151, MType({0x3939b586c46792b3, 0xc434de73b5c354c4})},
- {Sign::NEG, -151, MType({0xc619ea6a7a9ee85e, 0xb8aa3acd06fa999b})},
- {Sign::NEG, -151, MType({0x4b5656ef9e7a27fd, 0xad1f97259f87a4bb})},
- {Sign::NEG, -151, MType({0xb3a7d90083f7239c, 0xa194f37d7f6a760b})},
- {Sign::NEG, -151, MType({0xe9c74a3381c0f016, 0x960a4fd4a6a30d75})},
- {Sign::NEG, -151, MType({0xd86d7fcaf12ed012, 0x8a7fac2b15316ae2})},
- {Sign::NEG, -152, MType({0xd4a6956a5c863e0f, 0xfdea1101962b1c76})},
- {Sign::NEG, -152, MType({0x1462ef192f547877, 0xe6d4c9ab909eeed1})},
- {Sign::NEG, -152, MType({0x45819d2f1d72eb8b, 0xcfbf825419be4ca6})},
- {Sign::NEG, -152, MType({0x3d742790eedbe719, 0xb8aa3afb318935c8})},
- {Sign::NEG, -152, MType({0xd1ac0d7b70d74492, 0xa194f3a0d7ffaa08})},
- {Sign::NEG, -152, MType({0xd79ac58375f83d0c, 0x8a7fac450d21a939})},
- {Sign::NEG, -153, MType({0x49637b2bac367e87, 0xe6d4c9cfa1de665a})},
- {Sign::NEG, -153, MType({0x1cc4b5eedcc78b35, 0xb8aa3b1246d08f69})},
- {Sign::NEG, -153, MType({0xd43bf48a42745836, 0x8a7fac520919cd43})},
- {Sign::NEG, -154, MType({0x3557bdcf592619eb, 0xb8aa3b1dd1743f1c})},
- {Sign::NEG, -155, MType({0x6bdc2e83d3ebb0c4, 0xb8aa3b2396c617ae})},
- {Sign::POS, 0, MType({0x0, 0x0})},
- {Sign::POS, -155, MType({0x2d5b40050e44e8ab, 0xb8aa3b2f2169ca44})},
- {Sign::POS, -154, MType({0xb8560371b8f04afe, 0xb8aa3b34e6bba447})},
- {Sign::POS, -153, MType({0xc79a43ccc70459cc, 0x8a7fac6c010a1f14})},
- {Sign::POS, -153, MType({0x22c25632f519f77f, 0xb8aa3b40715f59c0})},
- {Sign::POS, -153, MType({0x42c10a314e35fb9e, 0xe6d4ca17c45d8282})},
- {Sign::POS, -152, MType({0xbe5a212ed7b949e4, 0x8a7fac78fd024cdb})},
- {Sign::POS, -152, MType({0x12dcf94ef5c5b918, 0xa194f3e7892a4fde})},
- {Sign::POS, -152, MType({0x49781013e57110ce, 0xb8aa3b5786a6ca76})},
- {Sign::POS, -152, MType({0x8cba70c085c12cb3, 0xcfbf82c8f577bcd2})},
- {Sign::POS, -152, MType({0x7332f3fb09328b8, 0xe6d4ca3bd59d2721})},
- {Sign::POS, -152, MType({0xe37168243a9d8b14, 0xfdea11b02717098f})},
- {Sign::POS, -151, MType({0xa602205479b93722, 0x8a7fac92f4f2b226})},
- {Sign::POS, -151, MType({0xb5bd735852c0d583, 0x960a504e8f041bc3})},
- {Sign::POS, -151, MType({0x363248630b0d812d, 0xa194f40ae1bfc1b6})},
- {Sign::POS, -151, MType({0x3ca83f0e02b823c0, 0xad1f97c7ed25a415})},
- {Sign::POS, -151, MType({0xde66fb46974bc4fd, 0xb8aa3b85b135c2f7})},
- {Sign::POS, -151, MType({0x30b6254e23c69fc2, 0xc434df442df01e75})},
- {Sign::POS, -151, MType({0x48dd69ba009b370c, 0xcfbf83036354b6a4})},
- {Sign::POS, -151, MType({0x3c24797383b16af5, 0xdb4a26c351638b9c})},
- {Sign::POS, -151, MType({0x1fd309b800678db7, 0xe6d4ca83f81c9d74})},
- {Sign::POS, -151, MType({0x930d418c79378a3, 0xf25f6e45577fec43})},
- {Sign::POS, -151, MType({0xd85967b2783a12c, 0xfdea12076f8d7820})},
- {Sign::POS, -150, MType({0x210c898c360016ed, 0x84ba5ae52022a091})},
- {Sign::POS, -150, MType({0x5e19883eef2605ab, 0x8a7facc6e4d3a3b0})},
- {Sign::POS, -150, MType({0x488dacc6629300ae, 0x9044fea905d9c579})},
- {Sign::POS, -150, MType({0x6b0cdebd3264e3e3, 0x960a508b833505f7})},
- {Sign::POS, -150, MType({0x503b07e7ff788dc2, 0x9bcfa26e5ce56536})},
- {Sign::POS, -150, MType({0x82bc1435696a69d1, 0xa194f45192eae341})},
- {Sign::POS, -150, MType({0x8d33f1be0e96fb1f, 0xa75a463525458024})},
- {Sign::POS, -150, MType({0xfa4690c48c1b66c9, 0xad1f981913f53bea})},
- {Sign::POS, -150, MType({0x5497e3b57dd5fe75, 0xb2e4e9fd5efa16a0})},
- {Sign::POS, -150, MType({0x26cbdf277e66cad5, 0xb8aa3be206541050})},
- {Sign::POS, -150, MType({0xfb8679db27301625, 0xbe6f8dc70a032905})},
- {Sign::POS, -150, MType({0x5d6bacbb1056f6aa, 0xc434dfac6a0760cd})},
- {Sign::POS, -150, MType({0xd71f72dbd0c3d936, 0xc9fa31922660b7b1})},
- {Sign::POS, -150, MType({0xf345c97bfe230ba2, 0xcfbf83783f0f2dbe})},
- {Sign::POS, -150, MType({0x3c82b0042ce54751, 0xd584d55eb412c300})},
- {Sign::POS, -150, MType({0x3d7a2806f0403bae, 0xdb4a2745856b7781})},
- {Sign::POS, -150, MType({0x80d03540da2f18ae, 0xe10f792cb3194b4d})},
- {Sign::POS, -150, MType({0x9128dd987b73194f, 0xe6d4cb143d1c3e70})},
- {Sign::POS, -150, MType({0xf928291e63940e14, 0xec9a1cfc237450f5})},
- {Sign::POS, -150, MType({0x4372220d20e0e78a, 0xf25f6ee4662182e9})},
- {Sign::POS, -150, MType({0xfaaad4c9407040c7, 0xf824c0cd0523d455})},
- {Sign::POS, -150, MType({0xa9764fe14e20e9e4, 0xfdea12b6007b4547})},
- {Sign::POS, -149, MType({0xed3c5206ea4d3942, 0x81d7b24fac13eae4})},
- {Sign::POS, -149, MType({0xc2af218aea6da27, 0x84ba5b448614c2f4})},
- {Sign::POS, -149, MType({0xf6d912ac383aaeba, 0x879d04398e402ad6})},
- {Sign::POS, -149, MType({0x7298bf5cca8b3d95, 0x8a7fad2ec4962293})},
- {Sign::POS, -149, MType({0x44bc04daa8808214, 0x8d6256242916aa2f})},
- {Sign::POS, -149, MType({0x3294f0eb14683198, 0x9044ff19bbc1c1b0})},
- {Sign::POS, -149, MType({0x17592684ff600c3, 0x9327a80f7c97691c})},
- {Sign::POS, -149, MType({0x76aff9419c43e8b9, 0x960a51056b97a078})},
- {Sign::POS, -149, MType({0x5796367b39d26c63, 0x98ecf9fb88c267cb})},
- {Sign::POS, -149, MType({0x697a5c2e6888ddaa, 0x9bcfa2f1d417bf1a})},
- {Sign::POS, -149, MType({0x71ae7d8967b5a2b7, 0x9eb24be84d97a66b})},
- {Sign::POS, -149, MType({0x3584aecf760e7b39, 0xa194f4def5421dc4})},
- {Sign::POS, -149, MType({0x7a4f0558d1b0c59e, 0xa4779dd5cb17252a})},
- {Sign::POS, -149, MType({0x55f9792b821c455, 0xa75a46cccf16bca4})},
- {Sign::POS, -149, MType({0x9c087cff664ee311, 0xaa3cefc40140e436})},
- {Sign::POS, -149, MType({0x39bce36188dfc04, 0xad1f98bb61959be8})},
- {Sign::POS, -149, MType({0x16ba4e30a9d9d21, 0xb00241b2f014e3be})},
- {Sign::POS, -149, MType({0x5aca1bc777a54d5e, 0xb2e4eaaaacbebbbe})},
- {Sign::POS, -149, MType({0xd5094eb99a35d1f0, 0xb5c793a2979323ee})},
- {Sign::POS, -149, MType({0x357b5aa4ac49738d, 0xb8aa3c9ab0921c55})},
+ {Sign::NEG, -149, 0xbb8ce299'0b5d0b90'ef1bffe5'65ce0a46_u128},
+ {Sign::NEG, -149, 0xb8aa39b8'07a576e4'bea32445'60ca3d99_u128},
+ {Sign::NEG, -149, 0xb5c790d6'd5c354df'8b91f71c'eefa31a2_u128},
+ {Sign::NEG, -149, 0xb2e4e7f5'75b6a57b'9096e3d6'84001c0e_u128},
+ {Sign::NEG, -149, 0xb0023f13'e77f68b3'086054c7'94367f36_u128},
+ {Sign::NEG, -149, 0xad1f9632'2b1d9e80'2d9cb330'94afe4de_u128},
+ {Sign::NEG, -149, 0xaa3ced50'409146dd'3afa673c'fb3698f3_u128},
+ {Sign::NEG, -149, 0xa75a446e'27da61c4'6b27d803'3e4c6450_u128},
+ {Sign::NEG, -149, 0xa4779b8b'e0f8ef2f'f8d36b84'd52a477b_u128},
+ {Sign::NEG, -149, 0xa194f2a9'6becef1a'1eab86ae'37c03565_u128},
+ {Sign::NEG, -149, 0x9eb249c6'c8b6617d'175e8d56'deb4ce2c_u128},
+ {Sign::NEG, -149, 0x9bcfa0e3'f7554653'1d9ae241'436519da_u128},
+ {Sign::NEG, -149, 0x98ecf800'f7c99d96'6c0ee71a'dfe44325_u128},
+ {Sign::NEG, -149, 0x960a4f1d'ca136741'3d68fc7c'2efb522f_u128},
+ {Sign::NEG, -149, 0x9327a63a'6e32a34d'cc5781e8'ac28e749_u128},
+ {Sign::NEG, -149, 0x9044fd56'e42751b6'5388d5ce'd3a0f5af_u128},
+ {Sign::NEG, -149, 0x8d625473'2bf17275'0dab5588'224c7e4a_u128},
+ {Sign::NEG, -149, 0x8a7fab8f'45910584'356d5d59'15c94a70_u128},
+ {Sign::NEG, -149, 0x879d02ab'31060ade'057d4871'2c69a6a7_u128},
+ {Sign::NEG, -149, 0x84ba59c6'ee50827c'b88970ea'e5341d60_u128},
+ {Sign::NEG, -149, 0x81d7b0e2'7d706c5a'89402fcb'bfe331bb_u128},
+ {Sign::NEG, -150, 0xfdea0ffb'bccb90e3'649fba08'79ca348b_u128},
+ {Sign::NEG, -150, 0xf824be32'22612d78'dccd9edf'bab6f777_u128},
+ {Sign::NEG, -150, 0xf25f6c68'2ba1ae69'f066b9aa'4636478e_u128},
+ {Sign::NEG, -150, 0xec9a1a9d'd88d13ab'14c7b3cb'21578781_u128},
+ {Sign::NEG, -150, 0xe6d4c8d3'29235d30'bf4d347b'528f56e1_u128},
+ {Sign::NEG, -150, 0xe10f7708'1d648aef'6553e0c9'e1b70799_u128},
+ {Sign::NEG, -150, 0xdb4a253c'b5509cdb'7c385b9b'd80c1375_u128},
+ {Sign::NEG, -150, 0xd584d370'f0e792e9'795745ac'402f919d_u128},
+ {Sign::NEG, -150, 0xcfbf81a4'd0296d0d'd20d3d8c'2625ac1b_u128},
+ {Sign::NEG, -150, 0xc9fa2fd8'53162b3c'fbb6dfa2'97551554_u128},
+ {Sign::NEG, -150, 0xc434de0b'79adcd6b'6bb0c62c'a2867d91_u128},
+ {Sign::NEG, -150, 0xbe6f8c3e'43f0538d'9757893d'57e40877_u128},
+ {Sign::NEG, -150, 0xb8aa3a70'b1ddbd97'f407bebd'c8f8c28e_u128},
+ {Sign::NEG, -150, 0xb2e4e8a2'c3760b7e'f71dfa6d'08b016be_u128},
+ {Sign::NEG, -150, 0xad1f96d4'78b93d37'15f6cde0'2b5543ce_u128},
+ {Sign::NEG, -150, 0xa75a4505'd1a752b4'c5eec882'4692d1e9_u128},
+ {Sign::NEG, -150, 0xa194f336'ce404bec'7c627794'7172081a_u128},
+ {Sign::NEG, -150, 0x9bcfa167'6e8428d2'aeae662d'c45a61ce_u128},
+ {Sign::NEG, -150, 0x960a4f97'b272e95b'd22f1d3b'59110455_u128},
+ {Sign::NEG, -150, 0x9044fdc7'9a0c8d7c'5c412380'4ab83462_u128},
+ {Sign::NEG, -150, 0x8a7fabf7'25511528'c240fd95'b5cecb89_u128},
+ {Sign::NEG, -150, 0x84ba5a26'54408055'798b2dea'b82fadc4_u128},
+ {Sign::NEG, -151, 0xfdea10aa'4db59ded'eef86988'e2227ddb_u128},
+ {Sign::NEG, -151, 0xf25f6d07'3a400203'62e1207c'0209b090_u128},
+ {Sign::NEG, -151, 0xe6d4c963'6e202cd4'39897891'13ec7bee_u128},
+ {Sign::NEG, -151, 0xdb4a25be'e9561e49'5daa6556'5e562909_u128},
+ {Sign::NEG, -151, 0xcfbf8219'abe1d64b'b9fcd606'2a84acbd_u128},
+ {Sign::NEG, -151, 0xc434de73'b5c354c4'3939b586'c46792b3_u128},
+ {Sign::NEG, -151, 0xb8aa3acd'06fa999b'c619ea6a'7a9ee85e_u128},
+ {Sign::NEG, -151, 0xad1f9725'9f87a4bb'4b5656ef'9e7a27fd_u128},
+ {Sign::NEG, -151, 0xa194f37d'7f6a760b'b3a7d900'83f7239c_u128},
+ {Sign::NEG, -151, 0x960a4fd4'a6a30d75'e9c74a33'81c0f016_u128},
+ {Sign::NEG, -151, 0x8a7fac2b'15316ae2'd86d7fca'f12ed012_u128},
+ {Sign::NEG, -152, 0xfdea1101'962b1c76'd4a6956a'5c863e0f_u128},
+ {Sign::NEG, -152, 0xe6d4c9ab'909eeed1'1462ef19'2f547877_u128},
+ {Sign::NEG, -152, 0xcfbf8254'19be4ca6'45819d2f'1d72eb8b_u128},
+ {Sign::NEG, -152, 0xb8aa3afb'318935c8'3d742790'eedbe719_u128},
+ {Sign::NEG, -152, 0xa194f3a0'd7ffaa08'd1ac0d7b'70d74492_u128},
+ {Sign::NEG, -152, 0x8a7fac45'0d21a939'd79ac583'75f83d0c_u128},
+ {Sign::NEG, -153, 0xe6d4c9cf'a1de665a'49637b2b'ac367e87_u128},
+ {Sign::NEG, -153, 0xb8aa3b12'46d08f69'1cc4b5ee'dcc78b35_u128},
+ {Sign::NEG, -153, 0x8a7fac52'0919cd43'd43bf48a'42745836_u128},
+ {Sign::NEG, -154, 0xb8aa3b1d'd1743f1c'3557bdcf'592619eb_u128},
+ {Sign::NEG, -155, 0xb8aa3b23'96c617ae'6bdc2e83'd3ebb0c4_u128},
+ {Sign::POS, 0, 0_u128},
+ {Sign::POS, -155, 0xb8aa3b2f'2169ca44'2d5b4005'0e44e8ab_u128},
+ {Sign::POS, -154, 0xb8aa3b34'e6bba447'b8560371'b8f04afe_u128},
+ {Sign::POS, -153, 0x8a7fac6c'010a1f14'c79a43cc'c70459cc_u128},
+ {Sign::POS, -153, 0xb8aa3b40'715f59c0'22c25632'f519f77f_u128},
+ {Sign::POS, -153, 0xe6d4ca17'c45d8282'42c10a31'4e35fb9e_u128},
+ {Sign::POS, -152, 0x8a7fac78'fd024cdb'be5a212e'd7b949e4_u128},
+ {Sign::POS, -152, 0xa194f3e7'892a4fde'12dcf94e'f5c5b918_u128},
+ {Sign::POS, -152, 0xb8aa3b57'86a6ca76'49781013'e57110ce_u128},
+ {Sign::POS, -152, 0xcfbf82c8'f577bcd2'8cba70c0'85c12cb3_u128},
+ {Sign::POS, -152, 0xe6d4ca3b'd59d2721'07332f3f'b09328b8_u128},
+ {Sign::POS, -152, 0xfdea11b0'2717098f'e3716824'3a9d8b14_u128},
+ {Sign::POS, -151, 0x8a7fac92'f4f2b226'a6022054'79b93722_u128},
+ {Sign::POS, -151, 0x960a504e'8f041bc3'b5bd7358'52c0d583_u128},
+ {Sign::POS, -151, 0xa194f40a'e1bfc1b6'36324863'0b0d812d_u128},
+ {Sign::POS, -151, 0xad1f97c7'ed25a415'3ca83f0e'02b823c0_u128},
+ {Sign::POS, -151, 0xb8aa3b85'b135c2f7'de66fb46'974bc4fd_u128},
+ {Sign::POS, -151, 0xc434df44'2df01e75'30b6254e'23c69fc2_u128},
+ {Sign::POS, -151, 0xcfbf8303'6354b6a4'48dd69ba'009b370c_u128},
+ {Sign::POS, -151, 0xdb4a26c3'51638b9c'3c247973'83b16af5_u128},
+ {Sign::POS, -151, 0xe6d4ca83'f81c9d74'1fd309b8'00678db7_u128},
+ {Sign::POS, -151, 0xf25f6e45'577fec43'0930d418'c79378a3_u128},
+ {Sign::POS, -151, 0xfdea1207'6f8d7820'0d85967b'2783a12c_u128},
+ {Sign::POS, -150, 0x84ba5ae5'2022a091'210c898c'360016ed_u128},
+ {Sign::POS, -150, 0x8a7facc6'e4d3a3b0'5e19883e'ef2605ab_u128},
+ {Sign::POS, -150, 0x9044fea9'05d9c579'488dacc6'629300ae_u128},
+ {Sign::POS, -150, 0x960a508b'833505f7'6b0cdebd'3264e3e3_u128},
+ {Sign::POS, -150, 0x9bcfa26e'5ce56536'503b07e7'ff788dc2_u128},
+ {Sign::POS, -150, 0xa194f451'92eae341'82bc1435'696a69d1_u128},
+ {Sign::POS, -150, 0xa75a4635'25458024'8d33f1be'0e96fb1f_u128},
+ {Sign::POS, -150, 0xad1f9819'13f53bea'fa4690c4'8c1b66c9_u128},
+ {Sign::POS, -150, 0xb2e4e9fd'5efa16a0'5497e3b5'7dd5fe75_u128},
+ {Sign::POS, -150, 0xb8aa3be2'06541050'26cbdf27'7e66cad5_u128},
+ {Sign::POS, -150, 0xbe6f8dc7'0a032905'fb8679db'27301625_u128},
+ {Sign::POS, -150, 0xc434dfac'6a0760cd'5d6bacbb'1056f6aa_u128},
+ {Sign::POS, -150, 0xc9fa3192'2660b7b1'd71f72db'd0c3d936_u128},
+ {Sign::POS, -150, 0xcfbf8378'3f0f2dbe'f345c97b'fe230ba2_u128},
+ {Sign::POS, -150, 0xd584d55e'b412c300'3c82b004'2ce54751_u128},
+ {Sign::POS, -150, 0xdb4a2745'856b7781'3d7a2806'f0403bae_u128},
+ {Sign::POS, -150, 0xe10f792c'b3194b4d'80d03540'da2f18ae_u128},
+ {Sign::POS, -150, 0xe6d4cb14'3d1c3e70'9128dd98'7b73194f_u128},
+ {Sign::POS, -150, 0xec9a1cfc'237450f5'f928291e'63940e14_u128},
+ {Sign::POS, -150, 0xf25f6ee4'662182e9'4372220d'20e0e78a_u128},
+ {Sign::POS, -150, 0xf824c0cd'0523d455'faaad4c9'407040c7_u128},
+ {Sign::POS, -150, 0xfdea12b6'007b4547'a9764fe1'4e20e9e4_u128},
+ {Sign::POS, -149, 0x81d7b24f'ac13eae4'ed3c5206'ea4d3942_u128},
+ {Sign::POS, -149, 0x84ba5b44'8614c2f4'0c2af218'aea6da27_u128},
+ {Sign::POS, -149, 0x879d0439'8e402ad6'f6d912ac'383aaeba_u128},
+ {Sign::POS, -149, 0x8a7fad2e'c4962293'7298bf5c'ca8b3d95_u128},
+ {Sign::POS, -149, 0x8d625624'2916aa2f'44bc04da'a8808214_u128},
+ {Sign::POS, -149, 0x9044ff19'bbc1c1b0'3294f0eb'14683198_u128},
+ {Sign::POS, -149, 0x9327a80f'7c97691c'01759268'4ff600c3_u128},
+ {Sign::POS, -149, 0x960a5105'6b97a078'76aff941'9c43e8b9_u128},
+ {Sign::POS, -149, 0x98ecf9fb'88c267cb'5796367b'39d26c63_u128},
+ {Sign::POS, -149, 0x9bcfa2f1'd417bf1a'697a5c2e'6888ddaa_u128},
+ {Sign::POS, -149, 0x9eb24be8'4d97a66b'71ae7d89'67b5a2b7_u128},
+ {Sign::POS, -149, 0xa194f4de'f5421dc4'3584aecf'760e7b39_u128},
+ {Sign::POS, -149, 0xa4779dd5'cb17252a'7a4f0558'd1b0c59e_u128},
+ {Sign::POS, -149, 0xa75a46cc'cf16bca4'055f9792'b821c455_u128},
+ {Sign::POS, -149, 0xaa3cefc4'0140e436'9c087cff'664ee311_u128},
+ {Sign::POS, -149, 0xad1f98bb'61959be8'039bce36'188dfc04_u128},
+ {Sign::POS, -149, 0xb00241b2'f014e3be'016ba4e3'0a9d9d21_u128},
+ {Sign::POS, -149, 0xb2e4eaaa'acbebbbe'5aca1bc7'77a54d5e_u128},
+ {Sign::POS, -149, 0xb5c793a2'979323ee'd5094eb9'9a35d1f0_u128},
+ {Sign::POS, -149, 0xb8aa3c9a'b0921c55'357b5aa4'ac49738d_u128},
}};
// > P = fpminimax(log2(1 + x)/x, 3, [|128...|], [-0x1.0002143p-29 , 0x1p-29]);
// > P;
// > dirtyinfnorm(log2(1 + x)/x - P, [-0x1.0002143p-29 , 0x1p-29]);
// 0x1.27ad5...p-121
-const Float128 BIG_COEFFS[4]{
- {Sign::NEG, -129, MType({0x3eccf6940d66bbcc, 0xb8aa3b295c2b21e3})},
- {Sign::POS, -129, MType({0xee39a6d649394bb1, 0xf6384ee1d01febc9})},
- {Sign::NEG, -128, MType({0xbe87fed067ea2ad5, 0xb8aa3b295c17f0bb})},
- {Sign::POS, -127, MType({0xbe87fed0691d3e3f, 0xb8aa3b295c17f0bb})},
+constexpr Float128 BIG_COEFFS[4]{
+ {Sign::NEG, -129, 0xb8aa3b29'5c2b21e3'3eccf694'0d66bbcc_u128},
+ {Sign::POS, -129, 0xf6384ee1'd01febc9'ee39a6d6'49394bb1_u128},
+ {Sign::NEG, -128, 0xb8aa3b29'5c17f0bb'be87fed0'67ea2ad5_u128},
+ {Sign::POS, -127, 0xb8aa3b29'5c17f0bb'be87fed0'691d3e3f_u128},
};
// Reuse the output of the fast pass range reduction.
@@ -854,7 +857,7 @@ double log2_accurate(int e_x, int index, double m_x) {
LLVM_LIBC_FUNCTION(double, log2, (double x)) {
using FPBits_t = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
FPBits_t xbits(x);
uint64_t x_u = xbits.uintval();
diff --git a/src/math/generic/log2f.cpp b/src/math/generic/log2f.cpp
index 8651316d282c..c9f7b2121519 100644
--- a/src/math/generic/log2f.cpp
+++ b/src/math/generic/log2f.cpp
@@ -55,7 +55,7 @@ namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
uint32_t x_u = xbits.uintval();
diff --git a/src/math/generic/log_range_reduction.h b/src/math/generic/log_range_reduction.h
index 8c9b7d2eabeb..64c0fc3aa4f5 100644
--- a/src/math/generic/log_range_reduction.h
+++ b/src/math/generic/log_range_reduction.h
@@ -37,7 +37,6 @@ log_range_reduction(double m_x, const LogRR &log_table,
fputil::DyadicFloat<128> &sum) {
using Float128 = typename fputil::DyadicFloat<128>;
using MType = typename Float128::MantissaType;
- using Sign = fputil::Sign;
int64_t v = static_cast<int64_t>(m_x * 0x1.0p60); // ulp = 2^-60
diff --git a/src/math/generic/logbf.cpp b/src/math/generic/logbf.cpp
index 78aa33ebbf4a..9f9f7fbcfbb8 100644
--- a/src/math/generic/logbf.cpp
+++ b/src/math/generic/logbf.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of logbf function ---------------------------------===//
+//===-- Implementation of logbf function ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/src/math/generic/logbf128.cpp b/src/math/generic/logbf128.cpp
new file mode 100644
index 000000000000..090433d1fb86
--- /dev/null
+++ b/src/math/generic/logbf128.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of logbf128 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/logbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, logbf128, (float128 x)) { return fputil::logb(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/logf.cpp b/src/math/generic/logf.cpp
index 49d258ecc133..5296ba6bc13c 100644
--- a/src/math/generic/logf.cpp
+++ b/src/math/generic/logf.cpp
@@ -54,7 +54,7 @@ namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, logf, (float x)) {
constexpr double LOG_2 = 0x1.62e42fefa39efp-1;
using FPBits = typename fputil::FPBits<float>;
- using Sign = fputil::Sign;
+
FPBits xbits(x);
uint32_t x_u = xbits.uintval();
diff --git a/src/math/generic/lrintf128.cpp b/src/math/generic/lrintf128.cpp
new file mode 100644
index 000000000000..8e06062fc580
--- /dev/null
+++ b/src/math/generic/lrintf128.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of lrintf128 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/lrintf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, lrintf128, (float128 x)) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<float128,
+ long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/lroundf128.cpp b/src/math/generic/lroundf128.cpp
new file mode 100644
index 000000000000..f93c47503825
--- /dev/null
+++ b/src/math/generic/lroundf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of lroundf128 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/lroundf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, lroundf128, (float128 x)) {
+ return fputil::round_to_signed_integer<float128, long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/math_utils.h b/src/math/generic/math_utils.h
index e884fe2deae2..cced761fc8c8 100644
--- a/src/math/generic/math_utils.h
+++ b/src/math/generic/math_utils.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_SRC_MATH_GENERIC_MATH_UTILS_H
#define LLVM_LIBC_SRC_MATH_GENERIC_MATH_UTILS_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/errno/libc_errno.h"
-#include <math.h>
-
#include <stdint.h>
// TODO: evaluate which functions from this file are actually used.
diff --git a/src/math/generic/modff128.cpp b/src/math/generic/modff128.cpp
new file mode 100644
index 000000000000..6aef5f510a95
--- /dev/null
+++ b/src/math/generic/modff128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of modff128 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/modff128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, modff128, (float128 x, float128 *iptr)) {
+ return fputil::modf(x, *iptr);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nanf128.cpp b/src/math/generic/nanf128.cpp
new file mode 100644
index 000000000000..f087c9f074fd
--- /dev/null
+++ b/src/math/generic/nanf128.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of nanf128 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/nanf128.h"
+#include "src/__support/common.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nanf128, (const char *arg)) {
+ auto result = internal::strtonan<float128>(arg);
+ if (result.has_error())
+ libc_errno = result.error;
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextafterf128.cpp b/src/math/generic/nextafterf128.cpp
new file mode 100644
index 000000000000..905c89022ba1
--- /dev/null
+++ b/src/math/generic/nextafterf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextafterf128 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/nextafterf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nextafterf128, (float128 x, float128 y)) {
+ return fputil::nextafter(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextdown.cpp b/src/math/generic/nextdown.cpp
new file mode 100644
index 000000000000..51dee483b70e
--- /dev/null
+++ b/src/math/generic/nextdown.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdown 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/nextdown.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nextdown, (double x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextdownf.cpp b/src/math/generic/nextdownf.cpp
new file mode 100644
index 000000000000..857b412d64c3
--- /dev/null
+++ b/src/math/generic/nextdownf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownf 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/nextdownf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nextdownf, (float x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextdownf128.cpp b/src/math/generic/nextdownf128.cpp
new file mode 100644
index 000000000000..2585a13df3a3
--- /dev/null
+++ b/src/math/generic/nextdownf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownf128 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/nextdownf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nextdownf128, (float128 x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextdownl.cpp b/src/math/generic/nextdownl.cpp
new file mode 100644
index 000000000000..06a09c9daea5
--- /dev/null
+++ b/src/math/generic/nextdownl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownl 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/nextdownl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, nextdownl, (long double x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextup.cpp b/src/math/generic/nextup.cpp
new file mode 100644
index 000000000000..d75a336eefcc
--- /dev/null
+++ b/src/math/generic/nextup.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextup 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/nextup.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nextup, (double x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextupf.cpp b/src/math/generic/nextupf.cpp
new file mode 100644
index 000000000000..3b18dae4488d
--- /dev/null
+++ b/src/math/generic/nextupf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupf 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/nextupf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nextupf, (float x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextupf128.cpp b/src/math/generic/nextupf128.cpp
new file mode 100644
index 000000000000..7d862c30976c
--- /dev/null
+++ b/src/math/generic/nextupf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupf128 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/nextupf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nextupf128, (float128 x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nextupl.cpp b/src/math/generic/nextupl.cpp
new file mode 100644
index 000000000000..ccc52445eec5
--- /dev/null
+++ b/src/math/generic/nextupl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupl 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/nextupl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, nextupl, (long double x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/powf.cpp b/src/math/generic/powf.cpp
index 2c666bab6d62..0450ffd711ff 100644
--- a/src/math/generic/powf.cpp
+++ b/src/math/generic/powf.cpp
@@ -424,7 +424,7 @@ LIBC_INLINE bool larger_exponent(double a, double b) {
double powf_double_double(int idx_x, double dx, double y6, double lo6_hi,
const DoubleDouble &exp2_hi_mid) {
using DoubleBits = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
// Perform a second range reduction step:
// idx2 = round(2^14 * (dx + 2^-8)) = round ( dx * 2^14 + 2^6)
// dx2 = (1 + dx) * r2 - 1
@@ -513,7 +513,7 @@ double powf_double_double(int idx_x, double dx, double y6, double lo6_hi,
LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
using FloatBits = typename fputil::FPBits<float>;
using DoubleBits = typename fputil::FPBits<double>;
- using Sign = fputil::Sign;
+
FloatBits xbits(x), ybits(y);
uint32_t x_u = xbits.uintval();
diff --git a/src/math/generic/rintf128.cpp b/src/math/generic/rintf128.cpp
new file mode 100644
index 000000000000..ba9912d6f853
--- /dev/null
+++ b/src/math/generic/rintf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of rintf128 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/rintf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, rintf128, (float128 x)) {
+ return fputil::round_using_current_rounding_mode(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/roundeven.cpp b/src/math/generic/roundeven.cpp
new file mode 100644
index 000000000000..5f2adf9b5fce
--- /dev/null
+++ b/src/math/generic/roundeven.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundeven 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/roundeven.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, roundeven, (double x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/roundevenf.cpp b/src/math/generic/roundevenf.cpp
new file mode 100644
index 000000000000..353bec74ecf0
--- /dev/null
+++ b/src/math/generic/roundevenf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenf 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/roundevenf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, roundevenf, (float x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/roundevenf128.cpp b/src/math/generic/roundevenf128.cpp
new file mode 100644
index 000000000000..259388c86fd3
--- /dev/null
+++ b/src/math/generic/roundevenf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenf128 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/roundevenf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, roundevenf128, (float128 x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/roundevenl.cpp b/src/math/generic/roundevenl.cpp
new file mode 100644
index 000000000000..f8f429faeec8
--- /dev/null
+++ b/src/math/generic/roundevenl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenl 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/roundevenl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, roundevenl, (long double x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/roundf128.cpp b/src/math/generic/roundf128.cpp
new file mode 100644
index 000000000000..5b35d746d440
--- /dev/null
+++ b/src/math/generic/roundf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundf128 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/roundf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, roundf128, (float128 x)) {
+ return fputil::round(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/truncf128.cpp b/src/math/generic/truncf128.cpp
new file mode 100644
index 000000000000..ecf05fa73b35
--- /dev/null
+++ b/src/math/generic/truncf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of truncf128 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/truncf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, truncf128, (float128 x)) {
+ return fputil::trunc(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfp.cpp b/src/math/generic/ufromfp.cpp
new file mode 100644
index 000000000000..15800d67fd8d
--- /dev/null
+++ b/src/math/generic/ufromfp.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ufromfp 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/ufromfp.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, ufromfp, (double x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpf.cpp b/src/math/generic/ufromfpf.cpp
new file mode 100644
index 000000000000..898446ec45aa
--- /dev/null
+++ b/src/math/generic/ufromfpf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ufromfpf 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/ufromfpf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, ufromfpf, (float x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpf128.cpp b/src/math/generic/ufromfpf128.cpp
new file mode 100644
index 000000000000..cc728f35551c
--- /dev/null
+++ b/src/math/generic/ufromfpf128.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpf128 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/ufromfpf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, ufromfpf128,
+ (float128 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpl.cpp b/src/math/generic/ufromfpl.cpp
new file mode 100644
index 000000000000..bd353e9ebbb5
--- /dev/null
+++ b/src/math/generic/ufromfpl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpl 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/ufromfpl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, ufromfpl,
+ (long double x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpx.cpp b/src/math/generic/ufromfpx.cpp
new file mode 100644
index 000000000000..5ad95ff3061e
--- /dev/null
+++ b/src/math/generic/ufromfpx.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ufromfpx 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/ufromfpx.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, ufromfpx, (double x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpxf.cpp b/src/math/generic/ufromfpxf.cpp
new file mode 100644
index 000000000000..7c878489e8d2
--- /dev/null
+++ b/src/math/generic/ufromfpxf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ufromfpxf 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/ufromfpxf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, ufromfpxf, (float x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpxf128.cpp b/src/math/generic/ufromfpxf128.cpp
new file mode 100644
index 000000000000..57c290365e69
--- /dev/null
+++ b/src/math/generic/ufromfpxf128.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpxf128 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/ufromfpxf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, ufromfpxf128,
+ (float128 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/ufromfpxl.cpp b/src/math/generic/ufromfpxl.cpp
new file mode 100644
index 000000000000..9a8ba7aa5b91
--- /dev/null
+++ b/src/math/generic/ufromfpxl.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpxl 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/ufromfpxl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, ufromfpxl,
+ (long double x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/llround.cpp b/src/math/gpu/llround.cpp
deleted file mode 100644
index afd98308730a..000000000000
--- a/src/math/gpu/llround.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Implementation of the GPU llround 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/llround.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(long long, llround, (double x)) {
- return __builtin_llround(x);
-}
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/llroundf.cpp b/src/math/gpu/llroundf.cpp
deleted file mode 100644
index 897ed15b6928..000000000000
--- a/src/math/gpu/llroundf.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Implementation of the GPU llroundf 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/llroundf.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(long long, llroundf, (float x)) {
- return __builtin_lroundf(x);
-}
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/lround.cpp b/src/math/gpu/lround.cpp
deleted file mode 100644
index 51e8f2245af8..000000000000
--- a/src/math/gpu/lround.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Implementation of the GPU lround 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/lround.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(long, lround, (double x)) { return __builtin_lround(x); }
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/lroundf.cpp b/src/math/gpu/lroundf.cpp
deleted file mode 100644
index 2a6fe7200d8c..000000000000
--- a/src/math/gpu/lroundf.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Implementation of the GPU lroundf 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/lroundf.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(long, lroundf, (float x)) { return __builtin_lroundf(x); }
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/modf.cpp b/src/math/gpu/modf.cpp
deleted file mode 100644
index 07dbbd6059c3..000000000000
--- a/src/math/gpu/modf.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Implementation of the GPU modf 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/modf.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(double, modf, (double x, double *iptr)) {
- return __builtin_modf(x, iptr);
-}
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/modff.cpp b/src/math/gpu/modff.cpp
deleted file mode 100644
index ad35f9006b51..000000000000
--- a/src/math/gpu/modff.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Implementation of the GPU modff 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/modff.h"
-#include "src/__support/common.h"
-
-namespace LIBC_NAMESPACE {
-
-LLVM_LIBC_FUNCTION(float, modff, (float x, float *iptr)) {
- return __builtin_modff(x, iptr);
-}
-
-} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/amdgpu/amdgpu.h b/src/math/gpu/vendor/amdgpu/amdgpu.h
deleted file mode 100644
index 43961fc75982..000000000000
--- a/src/math/gpu/vendor/amdgpu/amdgpu.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- AMDGPU specific definitions for math support ----------------------===//
-//
-// Part of the LLVM Project, under the Apache 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_GPU_AMDGPU_H
-#define LLVM_LIBC_SRC_MATH_GPU_AMDGPU_H
-
-#include "declarations.h"
-#include "platform.h"
-
-#include "src/__support/macros/attributes.h"
-
-namespace LIBC_NAMESPACE {
-namespace internal {
-LIBC_INLINE double acos(double x) { return __ocml_acos_f64(x); }
-LIBC_INLINE float acosf(float x) { return __ocml_acos_f32(x); }
-LIBC_INLINE double acosh(double x) { return __ocml_acosh_f64(x); }
-LIBC_INLINE float acoshf(float x) { return __ocml_acosh_f32(x); }
-LIBC_INLINE double asin(double x) { return __ocml_asin_f64(x); }
-LIBC_INLINE float asinf(float x) { return __ocml_asin_f32(x); }
-LIBC_INLINE double asinh(double x) { return __ocml_asinh_f64(x); }
-LIBC_INLINE float asinhf(float x) { return __ocml_asinh_f32(x); }
-LIBC_INLINE double atan(double x) { return __ocml_atan_f64(x); }
-LIBC_INLINE float atanf(float x) { return __ocml_atan_f32(x); }
-LIBC_INLINE double atan2(double x, double y) { return __ocml_atan2_f64(x, y); }
-LIBC_INLINE float atan2f(float x, float y) { return __ocml_atan2_f32(x, y); }
-LIBC_INLINE double atanh(double x) { return __ocml_atanh_f64(x); }
-LIBC_INLINE float atanhf(float x) { return __ocml_atanh_f32(x); }
-LIBC_INLINE double cos(double x) { return __ocml_cos_f64(x); }
-LIBC_INLINE float cosf(float x) { return __ocml_cos_f32(x); }
-LIBC_INLINE double cosh(double x) { return __ocml_cosh_f64(x); }
-LIBC_INLINE float coshf(float x) { return __ocml_cosh_f32(x); }
-LIBC_INLINE double erf(double x) { return __ocml_erf_f64(x); }
-LIBC_INLINE float erff(float x) { return __ocml_erf_f32(x); }
-LIBC_INLINE double exp(double x) { return __builtin_exp(x); }
-LIBC_INLINE float expf(float x) { return __builtin_expf(x); }
-LIBC_INLINE double exp2(double x) { return __ocml_exp2_f64(x); }
-LIBC_INLINE float exp2f(float x) { return __ocml_exp2_f32(x); }
-LIBC_INLINE double exp10(double x) { return __ocml_exp10_f64(x); }
-LIBC_INLINE float exp10f(float x) { return __ocml_exp10_f32(x); }
-LIBC_INLINE double expm1(double x) { return __ocml_expm1_f64(x); }
-LIBC_INLINE float expm1f(float x) { return __ocml_expm1_f32(x); }
-LIBC_INLINE double fdim(double x, double y) { return __ocml_fdim_f64(x, y); }
-LIBC_INLINE float fdimf(float x, float y) { return __ocml_fdim_f32(x, y); }
-LIBC_INLINE double hypot(double x, double y) { return __ocml_hypot_f64(x, y); }
-LIBC_INLINE float hypotf(float x, float y) { return __ocml_hypot_f32(x, y); }
-LIBC_INLINE int ilogb(double x) { return __ocml_ilogb_f64(x); }
-LIBC_INLINE int ilogbf(float x) { return __ocml_ilogb_f32(x); }
-LIBC_INLINE double ldexp(double x, int i) { return __builtin_ldexp(x, i); }
-LIBC_INLINE float ldexpf(float x, int i) { return __builtin_ldexpf(x, i); }
-LIBC_INLINE long long llrint(double x) {
- return static_cast<long long>(__builtin_rint(x));
-}
-LIBC_INLINE long long llrintf(float x) {
- return static_cast<long long>(__builtin_rintf(x));
-}
-LIBC_INLINE double log10(double x) { return __ocml_log10_f64(x); }
-LIBC_INLINE float log10f(float x) { return __ocml_log10_f32(x); }
-LIBC_INLINE double log1p(double x) { return __ocml_log1p_f64(x); }
-LIBC_INLINE float log1pf(float x) { return __ocml_log1p_f32(x); }
-LIBC_INLINE double log2(double x) { return __ocml_log2_f64(x); }
-LIBC_INLINE float log2f(float x) { return __ocml_log2_f32(x); }
-LIBC_INLINE double log(double x) { return __ocml_log_f64(x); }
-LIBC_INLINE float logf(float x) { return __ocml_log_f32(x); }
-LIBC_INLINE long lrint(double x) {
- return static_cast<long>(__builtin_rint(x));
-}
-LIBC_INLINE long lrintf(float x) {
- return static_cast<long>(__builtin_rintf(x));
-}
-LIBC_INLINE double nextafter(double x, double y) {
- return __ocml_nextafter_f64(x, y);
-}
-LIBC_INLINE float nextafterf(float x, float y) {
- return __ocml_nextafter_f32(x, y);
-}
-LIBC_INLINE double pow(double x, double y) { return __ocml_pow_f64(x, y); }
-LIBC_INLINE float powf(float x, float y) { return __ocml_pow_f32(x, y); }
-LIBC_INLINE double sin(double x) { return __ocml_sin_f64(x); }
-LIBC_INLINE float sinf(float x) { return __ocml_sin_f32(x); }
-LIBC_INLINE void sincos(double x, double *sinptr, double *cosptr) {
- *sinptr = __ocml_sincos_f64(x, cosptr);
-}
-LIBC_INLINE void sincosf(float x, float *sinptr, float *cosptr) {
- *sinptr = __ocml_sincos_f32(x, cosptr);
-}
-LIBC_INLINE double sinh(double x) { return __ocml_sinh_f64(x); }
-LIBC_INLINE float sinhf(float x) { return __ocml_sinh_f32(x); }
-LIBC_INLINE double tan(double x) { return __ocml_tan_f64(x); }
-LIBC_INLINE float tanf(float x) { return __ocml_tan_f32(x); }
-LIBC_INLINE double tanh(double x) { return __ocml_tanh_f64(x); }
-LIBC_INLINE float tanhf(float x) { return __ocml_tanh_f32(x); }
-LIBC_INLINE double scalbn(double x, int i) {
- return __builtin_amdgcn_ldexp(x, i);
-}
-LIBC_INLINE float scalbnf(float x, int i) {
- return __builtin_amdgcn_ldexpf(x, i);
-}
-LIBC_INLINE double frexp(double x, int *nptr) {
- return __builtin_frexp(x, nptr);
-}
-LIBC_INLINE float frexpf(float x, int *nptr) {
- return __builtin_frexpf(x, nptr);
-}
-LIBC_INLINE double remquo(double x, double y, int *q) {
- int tmp;
- double r = __ocml_remquo_f64(x, y, (gpu::Private<int> *)&tmp);
- *q = tmp;
- return r;
-}
-LIBC_INLINE float remquof(float x, float y, int *q) {
- int tmp;
- float r = __ocml_remquo_f32(x, y, (gpu::Private<int> *)&tmp);
- *q = tmp;
- return r;
-}
-LIBC_INLINE double tgamma(double x) { return __ocml_tgamma_f64(x); }
-LIBC_INLINE float tgammaf(float x) { return __ocml_tgamma_f32(x); }
-
-} // namespace internal
-} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC_MATH_GPU_AMDGPU_H
diff --git a/src/math/gpu/vendor/amdgpu/platform.h b/src/math/gpu/vendor/amdgpu/platform.h
deleted file mode 100644
index 160a8508cd8b..000000000000
--- a/src/math/gpu/vendor/amdgpu/platform.h
+++ /dev/null
@@ -1,130 +0,0 @@
-//===-- AMDGPU specific platform definitions for math support -------------===//
-//
-// Part of the LLVM Project, under the Apache 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_GPU_AMDGPU_PLATFORM_H
-#define LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H
-
-#include "src/__support/macros/attributes.h"
-
-#include <stdint.h>
-
-namespace LIBC_NAMESPACE {
-
-// The ROCm device library uses control globals to alter codegen for the
-// different targets. To avoid needing to link them in manually we simply
-// define them here.
-extern "C" {
-
-// Disable unsafe math optimizations in the implementation.
-extern const LIBC_INLINE_VAR uint8_t __oclc_unsafe_math_opt = 0;
-
-// Disable denormalization at zero optimizations in the implementation.
-extern const LIBC_INLINE_VAR uint8_t __oclc_daz_opt = 0;
-
-// Disable rounding optimizations for 32-bit square roots.
-extern const LIBC_INLINE_VAR uint8_t __oclc_correctly_rounded_sqrt32 = 1;
-
-// Disable finite math optimizations.
-extern const LIBC_INLINE_VAR uint8_t __oclc_finite_only_opt = 0;
-
-#if defined(__gfx700__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7000;
-#elif defined(__gfx701__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7001;
-#elif defined(__gfx702__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7002;
-#elif defined(__gfx703__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7003;
-#elif defined(__gfx704__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7004;
-#elif defined(__gfx705__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 7005;
-#elif defined(__gfx801__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 8001;
-#elif defined(__gfx802__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 8002;
-#elif defined(__gfx803__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 8003;
-#elif defined(__gfx805__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 8005;
-#elif defined(__gfx810__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 8100;
-#elif defined(__gfx900__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9000;
-#elif defined(__gfx902__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9002;
-#elif defined(__gfx904__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9004;
-#elif defined(__gfx906__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9006;
-#elif defined(__gfx908__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9008;
-#elif defined(__gfx909__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9009;
-#elif defined(__gfx90a__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9010;
-#elif defined(__gfx90c__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9012;
-#elif defined(__gfx940__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9400;
-#elif defined(__gfx941__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9401;
-#elif defined(__gfx942__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9402;
-#elif defined(__gfx1010__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10100;
-#elif defined(__gfx1011__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10101;
-#elif defined(__gfx1012__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10102;
-#elif defined(__gfx1013__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10103;
-#elif defined(__gfx1030__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10300;
-#elif defined(__gfx1031__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10301;
-#elif defined(__gfx1032__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10302;
-#elif defined(__gfx1033__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10303;
-#elif defined(__gfx1034__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10304;
-#elif defined(__gfx1035__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10305;
-#elif defined(__gfx1036__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 10306;
-#elif defined(__gfx1100__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11000;
-#elif defined(__gfx1101__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11001;
-#elif defined(__gfx1102__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11002;
-#elif defined(__gfx1103__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11003;
-#elif defined(__gfx1150__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11500;
-#elif defined(__gfx1151__)
-extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 11501;
-#else
-#error "Unknown AMDGPU architecture"
-#endif
-}
-
-// These aliases cause clang to emit the control constants with ODR linkage.
-// This allows us to link against the symbols without preventing them from being
-// optimized out or causing symbol collisions.
-[[gnu::alias("__oclc_unsafe_math_opt")]] const uint8_t __oclc_unsafe_math_opt__;
-[[gnu::alias("__oclc_daz_opt")]] const uint8_t __oclc_daz_opt__;
-[[gnu::alias("__oclc_correctly_rounded_sqrt32")]] const uint8_t
- __oclc_correctly_rounded_sqrt32__;
-[[gnu::alias("__oclc_finite_only_opt")]] const uint8_t __oclc_finite_only_opt__;
-[[gnu::alias("__oclc_ISA_version")]] const uint32_t __oclc_ISA_version__;
-
-} // namespace LIBC_NAMESPACE
-
-#endif // LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H
diff --git a/src/math/gpu/vendor/common.h b/src/math/gpu/vendor/common.h
deleted file mode 100644
index 041a9a01c30e..000000000000
--- a/src/math/gpu/vendor/common.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- Common interface for compiling the GPU math -----------------------===//
-//
-// Part of the LLVM Project, under the Apache 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_GPU_COMMON_H
-#define LLVM_LIBC_SRC_MATH_GPU_COMMON_H
-
-#include "src/__support/macros/properties/architectures.h"
-
-#if defined(LIBC_TARGET_ARCH_IS_AMDGPU)
-#include "amdgpu/amdgpu.h"
-#elif defined(LIBC_TARGET_ARCH_IS_NVPTX)
-#include "nvptx/nvptx.h"
-#else
-#error "Unsupported platform"
-#endif
-
-#endif // LLVM_LIBC_SRC_MATH_GPU_COMMON_H
diff --git a/src/math/ilogbf128.h b/src/math/ilogbf128.h
new file mode 100644
index 000000000000..d8fe3b970973
--- /dev/null
+++ b/src/math/ilogbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ilogbf128 ---------------------*- 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_ILOGBF128_H
+#define LLVM_LIBC_SRC_MATH_ILOGBF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+int ilogbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ILOGBF128_H
diff --git a/src/math/ldexpf128.h b/src/math/ldexpf128.h
new file mode 100644
index 000000000000..7aa6ded3c8e4
--- /dev/null
+++ b/src/math/ldexpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ldexpf128 ---------------------*- 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_LDEXPF128_H
+#define LLVM_LIBC_SRC_MATH_LDEXPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 ldexpf128(float128 x, int exp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LDEXPF128_H
diff --git a/src/math/llogb.h b/src/math/llogb.h
new file mode 100644
index 000000000000..b51f89fc0416
--- /dev/null
+++ b/src/math/llogb.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogb -------------------------*- 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_LLOGB_H
+#define LLVM_LIBC_SRC_MATH_LLOGB_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogb(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGB_H
diff --git a/src/math/llogbf.h b/src/math/llogbf.h
new file mode 100644
index 000000000000..af4aa8a5b15c
--- /dev/null
+++ b/src/math/llogbf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbf ------------------------*- 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_LLOGBF_H
+#define LLVM_LIBC_SRC_MATH_LLOGBF_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBF_H
diff --git a/src/math/llogbf128.h b/src/math/llogbf128.h
new file mode 100644
index 000000000000..ce7c872a63db
--- /dev/null
+++ b/src/math/llogbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbf128 ---------------------*- 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_LLOGBF128_H
+#define LLVM_LIBC_SRC_MATH_LLOGBF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBF128_H
diff --git a/src/math/llogbl.h b/src/math/llogbl.h
new file mode 100644
index 000000000000..3c323a3af2a9
--- /dev/null
+++ b/src/math/llogbl.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbl ------------------------*- 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_LLOGBL_H
+#define LLVM_LIBC_SRC_MATH_LLOGBL_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBL_H
diff --git a/src/math/llrintf128.h b/src/math/llrintf128.h
new file mode 100644
index 000000000000..ac9c249342cc
--- /dev/null
+++ b/src/math/llrintf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llrintf128 --------------------*- 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_LLRINTF128_H
+#define LLVM_LIBC_SRC_MATH_LLRINTF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long long llrintf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLRINTF128_H
diff --git a/src/math/llroundf128.h b/src/math/llroundf128.h
new file mode 100644
index 000000000000..3245dfafc4d5
--- /dev/null
+++ b/src/math/llroundf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llroundf128 -------------------*- 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_LLROUNDF128_H
+#define LLVM_LIBC_SRC_MATH_LLROUNDF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long long llroundf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLROUNDF128_H
diff --git a/src/math/logbf128.h b/src/math/logbf128.h
new file mode 100644
index 000000000000..7823bbd615b8
--- /dev/null
+++ b/src/math/logbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for logbf128 ---------------------*- 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_LOGBF128_H
+#define LLVM_LIBC_SRC_MATH_LOGBF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 logbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LOGBF128_H
diff --git a/src/math/lrintf128.h b/src/math/lrintf128.h
new file mode 100644
index 000000000000..8f3f5ceabd3c
--- /dev/null
+++ b/src/math/lrintf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for lrintf128 ---------------------*- 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_LRINTF128_H
+#define LLVM_LIBC_SRC_MATH_LRINTF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long lrintf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LRINTF128_H
diff --git a/src/math/lroundf128.h b/src/math/lroundf128.h
new file mode 100644
index 000000000000..663b3732655b
--- /dev/null
+++ b/src/math/lroundf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for lroundf128 --------------------*- 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_LROUNDF128_H
+#define LLVM_LIBC_SRC_MATH_LROUNDF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+long lroundf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LROUNDF128_H
diff --git a/src/math/modff128.h b/src/math/modff128.h
new file mode 100644
index 000000000000..48e614be95b9
--- /dev/null
+++ b/src/math/modff128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for modff128 -----------------------*- 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_MODFF128_H
+#define LLVM_LIBC_SRC_MATH_MODFF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 modff128(float128 x, float128 *iptr);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_MODFF128_H
diff --git a/src/math/nanf128.h b/src/math/nanf128.h
new file mode 100644
index 000000000000..b06d14e2f945
--- /dev/null
+++ b/src/math/nanf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nanf128 -----------------------*- 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_NANF128_H
+#define LLVM_LIBC_SRC_MATH_NANF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nanf128(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NANF128_H
diff --git a/src/math/nextafterf128.h b/src/math/nextafterf128.h
new file mode 100644
index 000000000000..a404d33810ec
--- /dev/null
+++ b/src/math/nextafterf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nextafterf128 ------------------*- 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_NEXTAFTERF128_H
+#define LLVM_LIBC_SRC_MATH_NEXTAFTERF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nextafterf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTAFTERF128_H
diff --git a/src/math/nextdown.h b/src/math/nextdown.h
new file mode 100644
index 000000000000..8049b170ee72
--- /dev/null
+++ b/src/math/nextdown.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdown ----------------------*- 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_NEXTDOWN_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWN_H
+
+namespace LIBC_NAMESPACE {
+
+double nextdown(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWN_H
diff --git a/src/math/nextdownf.h b/src/math/nextdownf.h
new file mode 100644
index 000000000000..0a2f23480574
--- /dev/null
+++ b/src/math/nextdownf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdownf ---------------------*- 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_NEXTDOWNF_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNF_H
+
+namespace LIBC_NAMESPACE {
+
+float nextdownf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNF_H
diff --git a/src/math/nextdownf128.h b/src/math/nextdownf128.h
new file mode 100644
index 000000000000..0a3043bb431d
--- /dev/null
+++ b/src/math/nextdownf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nextdownf128 ------------------*- 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_NEXTDOWNF128_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nextdownf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNF128_H
diff --git a/src/math/nextdownl.h b/src/math/nextdownl.h
new file mode 100644
index 000000000000..9cb274a89b1c
--- /dev/null
+++ b/src/math/nextdownl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdownl ---------------------*- 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_NEXTDOWNL_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nextdownl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNL_H
diff --git a/src/math/nextup.h b/src/math/nextup.h
new file mode 100644
index 000000000000..97ae82270b06
--- /dev/null
+++ b/src/math/nextup.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextup ------------------------*- 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_NEXTUP_H
+#define LLVM_LIBC_SRC_MATH_NEXTUP_H
+
+namespace LIBC_NAMESPACE {
+
+double nextup(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUP_H
diff --git a/src/math/nextupf.h b/src/math/nextupf.h
new file mode 100644
index 000000000000..ffc0fa168a10
--- /dev/null
+++ b/src/math/nextupf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextupf -----------------------*- 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_NEXTUPF_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPF_H
+
+namespace LIBC_NAMESPACE {
+
+float nextupf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPF_H
diff --git a/src/math/nextupf128.h b/src/math/nextupf128.h
new file mode 100644
index 000000000000..b4429922e4be
--- /dev/null
+++ b/src/math/nextupf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nextupf128 --------------------*- 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_NEXTUPF128_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nextupf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPF128_H
diff --git a/src/math/nextupl.h b/src/math/nextupl.h
new file mode 100644
index 000000000000..cbc6a168e4be
--- /dev/null
+++ b/src/math/nextupl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextupl -----------------------*- 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_NEXTUPL_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nextupl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPL_H
diff --git a/src/math/gpu/vendor/acos.cpp b/src/math/nvptx/acos.cpp
index 83b674fa6ae3..da2c7952feba 100644
--- a/src/math/gpu/vendor/acos.cpp
+++ b/src/math/nvptx/acos.cpp
@@ -9,10 +9,10 @@
#include "src/math/acos.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, acos, (double x)) { return internal::acos(x); }
+LLVM_LIBC_FUNCTION(double, acos, (double x)) { return __nv_acos(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/acosf.cpp b/src/math/nvptx/acosf.cpp
index ac629761a439..8a4125f03b8c 100644
--- a/src/math/gpu/vendor/acosf.cpp
+++ b/src/math/nvptx/acosf.cpp
@@ -9,10 +9,10 @@
#include "src/math/acosf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return internal::acosf(x); }
+LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return __nv_acosf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/acosh.cpp b/src/math/nvptx/acosh.cpp
index cc1b8b572b3d..06f6e2922f56 100644
--- a/src/math/gpu/vendor/acosh.cpp
+++ b/src/math/nvptx/acosh.cpp
@@ -9,10 +9,10 @@
#include "src/math/acosh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, acosh, (double x)) { return internal::acosh(x); }
+LLVM_LIBC_FUNCTION(double, acosh, (double x)) { return __nv_acosh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/acoshf.cpp b/src/math/nvptx/acoshf.cpp
index a0384f89eed3..00e8053a5078 100644
--- a/src/math/gpu/vendor/acoshf.cpp
+++ b/src/math/nvptx/acoshf.cpp
@@ -9,10 +9,10 @@
#include "src/math/acoshf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return internal::acoshf(x); }
+LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return __nv_acoshf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/asin.cpp b/src/math/nvptx/asin.cpp
index 24a8a136e88e..74d92fded72b 100644
--- a/src/math/gpu/vendor/asin.cpp
+++ b/src/math/nvptx/asin.cpp
@@ -9,10 +9,10 @@
#include "src/math/asin.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, asin, (double x)) { return internal::asin(x); }
+LLVM_LIBC_FUNCTION(double, asin, (double x)) { return __nv_asin(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/asinf.cpp b/src/math/nvptx/asinf.cpp
index 595a48f82744..30544bc1313d 100644
--- a/src/math/gpu/vendor/asinf.cpp
+++ b/src/math/nvptx/asinf.cpp
@@ -9,10 +9,10 @@
#include "src/math/asinf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, asinf, (float x)) { return internal::asinf(x); }
+LLVM_LIBC_FUNCTION(float, asinf, (float x)) { return __nv_asinf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/asinh.cpp b/src/math/nvptx/asinh.cpp
index f417d9fd8c1f..0e5dbb47e667 100644
--- a/src/math/gpu/vendor/asinh.cpp
+++ b/src/math/nvptx/asinh.cpp
@@ -9,10 +9,10 @@
#include "src/math/asinh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, asinh, (double x)) { return internal::asinh(x); }
+LLVM_LIBC_FUNCTION(double, asinh, (double x)) { return __nv_asinh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/asinhf.cpp b/src/math/nvptx/asinhf.cpp
index 78e5543cf366..6648108646cd 100644
--- a/src/math/gpu/vendor/asinhf.cpp
+++ b/src/math/nvptx/asinhf.cpp
@@ -9,10 +9,10 @@
#include "src/math/asinhf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { return internal::asinhf(x); }
+LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { return __nv_asinhf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atan.cpp b/src/math/nvptx/atan.cpp
index 45d7f02c02cd..3af793a53ae5 100644
--- a/src/math/gpu/vendor/atan.cpp
+++ b/src/math/nvptx/atan.cpp
@@ -9,10 +9,10 @@
#include "src/math/atan.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, atan, (double x)) { return internal::atan(x); }
+LLVM_LIBC_FUNCTION(double, atan, (double x)) { return __nv_atan(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atan2.cpp b/src/math/nvptx/atan2.cpp
index 94e215e52ca6..0c54e0e04899 100644
--- a/src/math/gpu/vendor/atan2.cpp
+++ b/src/math/nvptx/atan2.cpp
@@ -9,12 +9,12 @@
#include "src/math/atan2.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, atan2, (double x, double y)) {
- return internal::atan2(x, y);
+ return __nv_atan2(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atan2f.cpp b/src/math/nvptx/atan2f.cpp
index 70caa568e32d..c3327d92c97e 100644
--- a/src/math/gpu/vendor/atan2f.cpp
+++ b/src/math/nvptx/atan2f.cpp
@@ -9,12 +9,12 @@
#include "src/math/atan2f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, atan2f, (float x, float y)) {
- return internal::atan2f(x, y);
+ return __nv_atan2f(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atanf.cpp b/src/math/nvptx/atanf.cpp
index 132c43d9e3af..559526297732 100644
--- a/src/math/gpu/vendor/atanf.cpp
+++ b/src/math/nvptx/atanf.cpp
@@ -9,10 +9,10 @@
#include "src/math/atanf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, atanf, (float x)) { return internal::atanf(x); }
+LLVM_LIBC_FUNCTION(float, atanf, (float x)) { return __nv_atanf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atanh.cpp b/src/math/nvptx/atanh.cpp
index 07a75fcbbfc7..6699d959df18 100644
--- a/src/math/gpu/vendor/atanh.cpp
+++ b/src/math/nvptx/atanh.cpp
@@ -9,10 +9,10 @@
#include "src/math/atanh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, atanh, (double x)) { return internal::atanh(x); }
+LLVM_LIBC_FUNCTION(double, atanh, (double x)) { return __nv_atanh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/atanhf.cpp b/src/math/nvptx/atanhf.cpp
index 521c4133243d..526b7b3e3712 100644
--- a/src/math/gpu/vendor/atanhf.cpp
+++ b/src/math/nvptx/atanhf.cpp
@@ -9,10 +9,10 @@
#include "src/math/atanhf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { return internal::atanhf(x); }
+LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { return __nv_atanhf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/ceil.cpp b/src/math/nvptx/ceil.cpp
new file mode 100644
index 000000000000..ad1407d61f62
--- /dev/null
+++ b/src/math/nvptx/ceil.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the ceil function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ceil.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return __builtin_ceil(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/ceilf.cpp b/src/math/nvptx/ceilf.cpp
new file mode 100644
index 000000000000..c4fc58d93603
--- /dev/null
+++ b/src/math/nvptx/ceilf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the ceilf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/ceilf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return __builtin_ceilf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/copysign.cpp b/src/math/nvptx/copysign.cpp
new file mode 100644
index 000000000000..6f804bdb90a1
--- /dev/null
+++ b/src/math/nvptx/copysign.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the copysign function for GPU -------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/copysign.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, copysign, (double x, double y)) {
+ return __builtin_copysign(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/copysignf.cpp b/src/math/nvptx/copysignf.cpp
new file mode 100644
index 000000000000..4d7e132462ac
--- /dev/null
+++ b/src/math/nvptx/copysignf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the copysignf function for GPU ------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/copysignf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, copysignf, (float x, float y)) {
+ return __builtin_copysignf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/cos.cpp b/src/math/nvptx/cos.cpp
index 37c7507911ec..185ad3cf9215 100644
--- a/src/math/gpu/vendor/cos.cpp
+++ b/src/math/nvptx/cos.cpp
@@ -9,10 +9,10 @@
#include "src/math/cos.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, cos, (double x)) { return internal::cos(x); }
+LLVM_LIBC_FUNCTION(double, cos, (double x)) { return __nv_cos(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/cosf.cpp b/src/math/nvptx/cosf.cpp
index 1bd42ba37e92..3d34de4be51b 100644
--- a/src/math/gpu/vendor/cosf.cpp
+++ b/src/math/nvptx/cosf.cpp
@@ -9,10 +9,10 @@
#include "src/math/cosf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return internal::cosf(x); }
+LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return __nv_cosf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/cosh.cpp b/src/math/nvptx/cosh.cpp
index 3be05e58b51d..179864c5f910 100644
--- a/src/math/gpu/vendor/cosh.cpp
+++ b/src/math/nvptx/cosh.cpp
@@ -9,10 +9,10 @@
#include "src/math/cosh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, cosh, (double x)) { return internal::cosh(x); }
+LLVM_LIBC_FUNCTION(double, cosh, (double x)) { return __nv_cosh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/coshf.cpp b/src/math/nvptx/coshf.cpp
index 1b945bbd7c47..9147499db97c 100644
--- a/src/math/gpu/vendor/coshf.cpp
+++ b/src/math/nvptx/coshf.cpp
@@ -9,10 +9,10 @@
#include "src/math/coshf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return internal::coshf(x); }
+LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return __nv_coshf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/nvptx/declarations.h b/src/math/nvptx/declarations.h
index 9cb2be67b85b..d41b16c8eec9 100644
--- a/src/math/gpu/vendor/nvptx/declarations.h
+++ b/src/math/nvptx/declarations.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H
-#define LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H
+#ifndef LLVM_LIBC_SRC_MATH_NVPTX_DECLARATIONS_H
+#define LLVM_LIBC_SRC_MATH_NVPTX_DECLARATIONS_H
namespace LIBC_NAMESPACE {
@@ -86,4 +86,4 @@ float __nv_tgammaf(float);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H
+#endif // LLVM_LIBC_SRC_MATH_NVPTX_DECLARATIONS_H
diff --git a/src/math/gpu/vendor/erf.cpp b/src/math/nvptx/erf.cpp
index 190321ca2599..5ea0177d5cd3 100644
--- a/src/math/gpu/vendor/erf.cpp
+++ b/src/math/nvptx/erf.cpp
@@ -9,10 +9,10 @@
#include "src/math/erf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, erf, (double x)) { return internal::erf(x); }
+LLVM_LIBC_FUNCTION(double, erf, (double x)) { return __nv_erf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/erff.cpp b/src/math/nvptx/erff.cpp
index a5a08be54b07..03fdceace8e9 100644
--- a/src/math/gpu/vendor/erff.cpp
+++ b/src/math/nvptx/erff.cpp
@@ -9,10 +9,10 @@
#include "src/math/erff.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, erff, (float x)) { return internal::erff(x); }
+LLVM_LIBC_FUNCTION(float, erff, (float x)) { return __nv_erff(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/exp.cpp b/src/math/nvptx/exp.cpp
index ee5a22019f6a..6bbe87ba2e78 100644
--- a/src/math/gpu/vendor/exp.cpp
+++ b/src/math/nvptx/exp.cpp
@@ -9,10 +9,10 @@
#include "src/math/exp.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, exp, (double x)) { return internal::exp(x); }
+LLVM_LIBC_FUNCTION(double, exp, (double x)) { return __nv_exp(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/exp10.cpp b/src/math/nvptx/exp10.cpp
index 8557a33f0188..11bb734fd113 100644
--- a/src/math/gpu/vendor/exp10.cpp
+++ b/src/math/nvptx/exp10.cpp
@@ -9,10 +9,10 @@
#include "src/math/exp10.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, exp10, (double x)) { return internal::exp10(x); }
+LLVM_LIBC_FUNCTION(double, exp10, (double x)) { return __nv_exp10(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/exp10f.cpp b/src/math/nvptx/exp10f.cpp
index 844809355087..4e3121a0b46e 100644
--- a/src/math/gpu/vendor/exp10f.cpp
+++ b/src/math/nvptx/exp10f.cpp
@@ -9,10 +9,10 @@
#include "src/math/exp10f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { return internal::exp10f(x); }
+LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { return __nv_exp10f(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/exp2.cpp b/src/math/nvptx/exp2.cpp
index ffa23d810a9b..35fc27b3a26a 100644
--- a/src/math/gpu/vendor/exp2.cpp
+++ b/src/math/nvptx/exp2.cpp
@@ -9,10 +9,10 @@
#include "src/math/exp2.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, exp2, (double x)) { return internal::exp2(x); }
+LLVM_LIBC_FUNCTION(double, exp2, (double x)) { return __nv_exp2(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/exp2f.cpp b/src/math/nvptx/exp2f.cpp
index cb61557383df..8d137346fe00 100644
--- a/src/math/gpu/vendor/exp2f.cpp
+++ b/src/math/nvptx/exp2f.cpp
@@ -9,10 +9,10 @@
#include "src/math/exp2f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { return internal::exp2f(x); }
+LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { return __nv_exp2f(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/expf.cpp b/src/math/nvptx/expf.cpp
index 89c194e4bc29..a6362bd73461 100644
--- a/src/math/gpu/vendor/expf.cpp
+++ b/src/math/nvptx/expf.cpp
@@ -9,10 +9,10 @@
#include "src/math/expf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, expf, (float x)) { return internal::expf(x); }
+LLVM_LIBC_FUNCTION(float, expf, (float x)) { return __nv_expf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/expm1.cpp b/src/math/nvptx/expm1.cpp
index 6ac5f753b9e4..0331903b8fd8 100644
--- a/src/math/gpu/vendor/expm1.cpp
+++ b/src/math/nvptx/expm1.cpp
@@ -9,10 +9,10 @@
#include "src/math/expm1.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, expm1, (double x)) { return internal::expm1(x); }
+LLVM_LIBC_FUNCTION(double, expm1, (double x)) { return __nv_expm1(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/expm1f.cpp b/src/math/nvptx/expm1f.cpp
index c5497797dbe1..7b74c548f3df 100644
--- a/src/math/gpu/vendor/expm1f.cpp
+++ b/src/math/nvptx/expm1f.cpp
@@ -9,10 +9,10 @@
#include "src/math/expm1f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { return internal::expm1f(x); }
+LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { return __nv_expm1f(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fabs.cpp b/src/math/nvptx/fabs.cpp
new file mode 100644
index 000000000000..c0d063d50ae5
--- /dev/null
+++ b/src/math/nvptx/fabs.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the fabs function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fabs.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fabs, (double x)) { return __builtin_fabs(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fabsf.cpp b/src/math/nvptx/fabsf.cpp
new file mode 100644
index 000000000000..398ffd0c74c0
--- /dev/null
+++ b/src/math/nvptx/fabsf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the fabsf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fabsf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fabsf, (float x)) { return __builtin_fabsf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/fdim.cpp b/src/math/nvptx/fdim.cpp
index f30dafb46e54..2f1ff5180026 100644
--- a/src/math/gpu/vendor/fdim.cpp
+++ b/src/math/nvptx/fdim.cpp
@@ -9,12 +9,12 @@
#include "src/math/fdim.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, fdim, (double x, double y)) {
- return internal::fdim(x, y);
+ return __nv_fdim(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/fdimf.cpp b/src/math/nvptx/fdimf.cpp
index e30736206a9a..c24e6be72482 100644
--- a/src/math/gpu/vendor/fdimf.cpp
+++ b/src/math/nvptx/fdimf.cpp
@@ -9,12 +9,12 @@
#include "src/math/fdimf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, fdimf, (float x, float y)) {
- return internal::fdimf(x, y);
+ return __nv_fdimf(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/floor.cpp b/src/math/nvptx/floor.cpp
new file mode 100644
index 000000000000..eada89c178d7
--- /dev/null
+++ b/src/math/nvptx/floor.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the floor function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/floor.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, floor, (double x)) { return __builtin_floor(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/floorf.cpp b/src/math/nvptx/floorf.cpp
new file mode 100644
index 000000000000..a5611c515a88
--- /dev/null
+++ b/src/math/nvptx/floorf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the floorf function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/floorf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, floorf, (float x)) { return __builtin_floorf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fma.cpp b/src/math/nvptx/fma.cpp
new file mode 100644
index 000000000000..41a6ddf60dbc
--- /dev/null
+++ b/src/math/nvptx/fma.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the fma function for GPU ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fma.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fma, (double x, double y, double z)) {
+ return __builtin_fma(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fmaf.cpp b/src/math/nvptx/fmaf.cpp
new file mode 100644
index 000000000000..c948e32f77eb
--- /dev/null
+++ b/src/math/nvptx/fmaf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the fmaf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmaf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaf, (float x, float y, float z)) {
+ return __builtin_fmaf(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/fmax.cpp b/src/math/nvptx/fmax.cpp
index a2c35371d12b..3ba65d7eccd3 100644
--- a/src/math/gpu/fmax.cpp
+++ b/src/math/nvptx/fmax.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/math/fmax.h"
+
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/nvptx/fmaxf.cpp b/src/math/nvptx/fmaxf.cpp
new file mode 100644
index 000000000000..e977082b39f4
--- /dev/null
+++ b/src/math/nvptx/fmaxf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmaxf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmaxf.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
+ return __builtin_fmaxf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fmin.cpp b/src/math/nvptx/fmin.cpp
new file mode 100644
index 000000000000..0d6f3521dcb7
--- /dev/null
+++ b/src/math/nvptx/fmin.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of the fmin function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmin.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
+ return __builtin_fmin(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fminf.cpp b/src/math/nvptx/fminf.cpp
new file mode 100644
index 000000000000..42744abfb3b0
--- /dev/null
+++ b/src/math/nvptx/fminf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of the fminf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fminf.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
+ return __builtin_fminf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fmod.cpp b/src/math/nvptx/fmod.cpp
new file mode 100644
index 000000000000..0654cdd2abe0
--- /dev/null
+++ b/src/math/nvptx/fmod.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the fmod function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmod.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmod, (double x, double y)) {
+ return __builtin_fmod(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/fmodf.cpp b/src/math/nvptx/fmodf.cpp
new file mode 100644
index 000000000000..b689046468fb
--- /dev/null
+++ b/src/math/nvptx/fmodf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the fmodf function for GPU ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/fmodf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmodf, (float x, float y)) {
+ return __builtin_fmodf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/frexp.cpp b/src/math/nvptx/frexp.cpp
index 5fc2c1409c6e..2423961f7c61 100644
--- a/src/math/gpu/vendor/frexp.cpp
+++ b/src/math/nvptx/frexp.cpp
@@ -9,12 +9,12 @@
#include "src/math/frexp.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, frexp, (double x, int *p)) {
- return internal::frexp(x, p);
+ return __nv_frexp(x, p);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/frexpf.cpp b/src/math/nvptx/frexpf.cpp
index e928d375e03d..f1ea29068777 100644
--- a/src/math/gpu/vendor/frexpf.cpp
+++ b/src/math/nvptx/frexpf.cpp
@@ -9,12 +9,12 @@
#include "src/math/frexpf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, frexpf, (float x, int *p)) {
- return internal::frexpf(x, p);
+ return __nv_frexpf(x, p);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/hypot.cpp b/src/math/nvptx/hypot.cpp
index 45b629e3e285..28bf04aa4a2b 100644
--- a/src/math/gpu/vendor/hypot.cpp
+++ b/src/math/nvptx/hypot.cpp
@@ -9,12 +9,12 @@
#include "src/math/hypot.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, hypot, (double x, double y)) {
- return internal::hypot(x, y);
+ return __nv_hypot(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/hypotf.cpp b/src/math/nvptx/hypotf.cpp
index 533e9dcb8dbf..c506aab1acc0 100644
--- a/src/math/gpu/vendor/hypotf.cpp
+++ b/src/math/nvptx/hypotf.cpp
@@ -9,12 +9,12 @@
#include "src/math/hypotf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
- return internal::hypotf(x, y);
+ return __nv_hypotf(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/ilogb.cpp b/src/math/nvptx/ilogb.cpp
index 1d075027b41c..fc75e2fd847a 100644
--- a/src/math/gpu/vendor/ilogb.cpp
+++ b/src/math/nvptx/ilogb.cpp
@@ -9,10 +9,10 @@
#include "src/math/ilogb.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return internal::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return __nv_ilogb(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/ilogbf.cpp b/src/math/nvptx/ilogbf.cpp
index 8dc2ff0a374a..3d14fcfa878f 100644
--- a/src/math/gpu/vendor/ilogbf.cpp
+++ b/src/math/nvptx/ilogbf.cpp
@@ -9,10 +9,10 @@
#include "src/math/ilogbf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return internal::ilogbf(x); }
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return __nv_ilogbf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/ldexp.cpp b/src/math/nvptx/ldexp.cpp
index f760a4256330..761dc4816b7a 100644
--- a/src/math/gpu/vendor/ldexp.cpp
+++ b/src/math/nvptx/ldexp.cpp
@@ -9,12 +9,12 @@
#include "src/math/ldexp.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, ldexp, (double x, int y)) {
- return internal::ldexp(x, y);
+ return __nv_ldexp(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/ldexpf.cpp b/src/math/nvptx/ldexpf.cpp
index d00d39115ffc..2d4c556a2714 100644
--- a/src/math/gpu/vendor/ldexpf.cpp
+++ b/src/math/nvptx/ldexpf.cpp
@@ -9,12 +9,12 @@
#include "src/math/ldexpf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, ldexpf, (float x, int y)) {
- return internal::ldexpf(x, y);
+ return __nv_ldexpf(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/llrint.cpp b/src/math/nvptx/llrint.cpp
new file mode 100644
index 000000000000..8f95e75e779b
--- /dev/null
+++ b/src/math/nvptx/llrint.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the llrint function for GPU ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/llrint.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long long, llrint, (double x)) { return __nv_llrint(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/llrintf.cpp b/src/math/nvptx/llrintf.cpp
new file mode 100644
index 000000000000..1432ffbd1bda
--- /dev/null
+++ b/src/math/nvptx/llrintf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the llrintf function for GPU --------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/llrintf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long long, llrintf, (float x)) { return __nv_llrintf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log.cpp b/src/math/nvptx/log.cpp
index a97689abcc21..26b6dfa607b9 100644
--- a/src/math/gpu/vendor/log.cpp
+++ b/src/math/nvptx/log.cpp
@@ -9,10 +9,10 @@
#include "src/math/log.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, log, (double x)) { return internal::log(x); }
+LLVM_LIBC_FUNCTION(double, log, (double x)) { return __nv_log(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log10.cpp b/src/math/nvptx/log10.cpp
index c7a917a75cc9..ff2702539567 100644
--- a/src/math/gpu/vendor/log10.cpp
+++ b/src/math/nvptx/log10.cpp
@@ -9,10 +9,10 @@
#include "src/math/log10.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, log10, (double x)) { return internal::log10(x); }
+LLVM_LIBC_FUNCTION(double, log10, (double x)) { return __nv_log10(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log10f.cpp b/src/math/nvptx/log10f.cpp
index 489f5f558be1..af903b60a7ce 100644
--- a/src/math/gpu/vendor/log10f.cpp
+++ b/src/math/nvptx/log10f.cpp
@@ -9,10 +9,10 @@
#include "src/math/log10f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, log10f, (float x)) { return internal::log10f(x); }
+LLVM_LIBC_FUNCTION(float, log10f, (float x)) { return __nv_log10f(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log1p.cpp b/src/math/nvptx/log1p.cpp
index 720d23e2f952..47bc96b0d881 100644
--- a/src/math/gpu/vendor/log1p.cpp
+++ b/src/math/nvptx/log1p.cpp
@@ -9,10 +9,10 @@
#include "src/math/log1p.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, log1p, (double x)) { return internal::log1p(x); }
+LLVM_LIBC_FUNCTION(double, log1p, (double x)) { return __nv_log1p(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log1pf.cpp b/src/math/nvptx/log1pf.cpp
index 96ad48b529cf..bfa4f7f22d54 100644
--- a/src/math/gpu/vendor/log1pf.cpp
+++ b/src/math/nvptx/log1pf.cpp
@@ -9,10 +9,10 @@
#include "src/math/log1pf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { return internal::log1pf(x); }
+LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { return __nv_log1pf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log2.cpp b/src/math/nvptx/log2.cpp
index 9fc8a81e7e75..86a980de65d4 100644
--- a/src/math/gpu/vendor/log2.cpp
+++ b/src/math/nvptx/log2.cpp
@@ -9,10 +9,10 @@
#include "src/math/log2.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, log2, (double x)) { return internal::log2(x); }
+LLVM_LIBC_FUNCTION(double, log2, (double x)) { return __nv_log2(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/log2f.cpp b/src/math/nvptx/log2f.cpp
index 62df41b69b0b..5ce46291610d 100644
--- a/src/math/gpu/vendor/log2f.cpp
+++ b/src/math/nvptx/log2f.cpp
@@ -9,10 +9,10 @@
#include "src/math/log2f.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, log2f, (float x)) { return internal::log2f(x); }
+LLVM_LIBC_FUNCTION(float, log2f, (float x)) { return __nv_log2f(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/logb.cpp b/src/math/nvptx/logb.cpp
index 5dea57d41b08..b620b16184fc 100644
--- a/src/math/gpu/vendor/logb.cpp
+++ b/src/math/nvptx/logb.cpp
@@ -9,10 +9,10 @@
#include "src/math/logb.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, logb, (double x)) { return internal::logb(x); }
+LLVM_LIBC_FUNCTION(double, logb, (double x)) { return __nv_logb(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/logbf.cpp b/src/math/nvptx/logbf.cpp
index 1a59df3e09a8..f19f0320db9d 100644
--- a/src/math/gpu/vendor/logbf.cpp
+++ b/src/math/nvptx/logbf.cpp
@@ -9,10 +9,10 @@
#include "src/math/logbf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return internal::logbf(x); }
+LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return __nv_logbf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/logf.cpp b/src/math/nvptx/logf.cpp
index 527b028e100d..6deb482c0ace 100644
--- a/src/math/gpu/vendor/logf.cpp
+++ b/src/math/nvptx/logf.cpp
@@ -9,10 +9,10 @@
#include "src/math/logf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, logf, (float x)) { return internal::logf(x); }
+LLVM_LIBC_FUNCTION(float, logf, (float x)) { return __nv_logf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/lrint.cpp b/src/math/nvptx/lrint.cpp
index a08996b755b5..8585f4ce53a4 100644
--- a/src/math/gpu/vendor/lrint.cpp
+++ b/src/math/nvptx/lrint.cpp
@@ -9,10 +9,10 @@
#include "src/math/lrint.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(long, lrint, (double x)) { return internal::lrint(x); }
+LLVM_LIBC_FUNCTION(long, lrint, (double x)) { return __nv_lrint(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/lrintf.cpp b/src/math/nvptx/lrintf.cpp
index 695a9b8202cf..312a9469fade 100644
--- a/src/math/gpu/vendor/lrintf.cpp
+++ b/src/math/nvptx/lrintf.cpp
@@ -9,10 +9,10 @@
#include "src/math/lrintf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(long, lrintf, (float x)) { return internal::lrintf(x); }
+LLVM_LIBC_FUNCTION(long, lrintf, (float x)) { return __nv_lrintf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/nearbyint.cpp b/src/math/nvptx/nearbyint.cpp
new file mode 100644
index 000000000000..9c7b600df708
--- /dev/null
+++ b/src/math/nvptx/nearbyint.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU nearbyint 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/nearbyint.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nearbyint, (double x)) {
+ return __builtin_nearbyint(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/nearbyintf.cpp b/src/math/nvptx/nearbyintf.cpp
new file mode 100644
index 000000000000..7fbe9f4f0e0b
--- /dev/null
+++ b/src/math/nvptx/nearbyintf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU nearbyintf 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/nearbyintf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nearbyintf, (float x)) {
+ return __builtin_nearbyintf(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/nextafter.cpp b/src/math/nvptx/nextafter.cpp
index f88e17f10908..171aaad6f7cc 100644
--- a/src/math/gpu/vendor/nextafter.cpp
+++ b/src/math/nvptx/nextafter.cpp
@@ -9,12 +9,12 @@
#include "src/math/nextafter.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, nextafter, (double x, double y)) {
- return internal::nextafter(x, y);
+ return __nv_nextafter(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/nextafterf.cpp b/src/math/nvptx/nextafterf.cpp
index 7a39dc8fc814..a45937c0dc8b 100644
--- a/src/math/gpu/vendor/nextafterf.cpp
+++ b/src/math/nvptx/nextafterf.cpp
@@ -9,12 +9,12 @@
#include "src/math/nextafterf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, nextafterf, (float x, float y)) {
- return internal::nextafterf(x, y);
+ return __nv_nextafterf(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/nvptx/nvptx.h b/src/math/nvptx/nvptx.h
index 110d570a84a3..5f9b32f311ea 100644
--- a/src/math/gpu/vendor/nvptx/nvptx.h
+++ b/src/math/nvptx/nvptx.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GPU_NVPTX_H
-#define LLVM_LIBC_SRC_MATH_GPU_NVPTX_H
+#ifndef LLVM_LIBC_SRC_MATH_NVPTX_NVPTX_H
+#define LLVM_LIBC_SRC_MATH_NVPTX_NVPTX_H
#include "declarations.h"
@@ -99,4 +99,4 @@ LIBC_INLINE float tgammaf(float x) { return __nv_tgammaf(x); }
} // namespace internal
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC_MATH_GPU_NVPTX_H
+#endif // LLVM_LIBC_SRC_MATH_NVPTX_NVPTX_H
diff --git a/src/math/nvptx/pow.cpp b/src/math/nvptx/pow.cpp
new file mode 100644
index 000000000000..7de3c9e7e544
--- /dev/null
+++ b/src/math/nvptx/pow.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the pow function for GPU ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/pow.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, pow, (double x, double y)) { return __nv_pow(x, y); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/powf.cpp b/src/math/nvptx/powf.cpp
new file mode 100644
index 000000000000..f9f7dbae63ac
--- /dev/null
+++ b/src/math/nvptx/powf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the powf function for GPU -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/powf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { return __nv_powf(x, y); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/remainder.cpp b/src/math/nvptx/remainder.cpp
new file mode 100644
index 000000000000..89b235f9c22a
--- /dev/null
+++ b/src/math/nvptx/remainder.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU remainder 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/remainder.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, remainder, (double x, double y)) {
+ return __builtin_remainder(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/remainderf.cpp b/src/math/nvptx/remainderf.cpp
new file mode 100644
index 000000000000..9fee6f856dc8
--- /dev/null
+++ b/src/math/nvptx/remainderf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the GPU remainderf 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/remainderf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, remainderf, (float x, float y)) {
+ return __builtin_remainderf(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/remquo.cpp b/src/math/nvptx/remquo.cpp
index e92c9b3c2a6e..da69a20f8f4f 100644
--- a/src/math/gpu/vendor/remquo.cpp
+++ b/src/math/nvptx/remquo.cpp
@@ -9,12 +9,12 @@
#include "src/math/remquo.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, remquo, (double x, double y, int *quo)) {
- return internal::remquo(x, y, quo);
+ return __nv_remquo(x, y, quo);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/remquof.cpp b/src/math/nvptx/remquof.cpp
index b234885aa88c..dcfba5d7b5fa 100644
--- a/src/math/gpu/vendor/remquof.cpp
+++ b/src/math/nvptx/remquof.cpp
@@ -9,12 +9,12 @@
#include "src/math/remquof.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, remquof, (float x, float y, int *quo)) {
- return internal::remquof(x, y, quo);
+ return __nv_remquof(x, y, quo);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/rint.cpp b/src/math/nvptx/rint.cpp
new file mode 100644
index 000000000000..44d494a8ed57
--- /dev/null
+++ b/src/math/nvptx/rint.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU rint 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/rint.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, rint, (double x)) { return __builtin_rint(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/rintf.cpp b/src/math/nvptx/rintf.cpp
new file mode 100644
index 000000000000..daf98d943605
--- /dev/null
+++ b/src/math/nvptx/rintf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU rintf 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/rintf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, rintf, (float x)) { return __builtin_rintf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/round.cpp b/src/math/nvptx/round.cpp
new file mode 100644
index 000000000000..9d8b5582f040
--- /dev/null
+++ b/src/math/nvptx/round.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU round 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/round.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, round, (double x)) { return __builtin_round(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/roundf.cpp b/src/math/nvptx/roundf.cpp
new file mode 100644
index 000000000000..8743e4eb7fb8
--- /dev/null
+++ b/src/math/nvptx/roundf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU roundf 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/roundf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, roundf, (float x)) { return __builtin_roundf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/scalbn.cpp b/src/math/nvptx/scalbn.cpp
index 435533a90501..80374db4c1c9 100644
--- a/src/math/gpu/vendor/scalbn.cpp
+++ b/src/math/nvptx/scalbn.cpp
@@ -9,12 +9,12 @@
#include "src/math/scalbn.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, scalbn, (double x, int y)) {
- return internal::scalbn(x, y);
+ return __nv_scalbn(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/scalbnf.cpp b/src/math/nvptx/scalbnf.cpp
index 0a4844c8a433..24fa3a5ed698 100644
--- a/src/math/gpu/vendor/scalbnf.cpp
+++ b/src/math/nvptx/scalbnf.cpp
@@ -9,12 +9,12 @@
#include "src/math/scalbnf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, scalbnf, (float x, int y)) {
- return internal::scalbnf(x, y);
+ return __nv_scalbnf(x, y);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sin.cpp b/src/math/nvptx/sin.cpp
index 96e07c99b71a..1bff129a0151 100644
--- a/src/math/gpu/vendor/sin.cpp
+++ b/src/math/nvptx/sin.cpp
@@ -9,10 +9,10 @@
#include "src/math/sin.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, sin, (double x)) { return internal::sin(x); }
+LLVM_LIBC_FUNCTION(double, sin, (double x)) { return __nv_sin(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sincos.cpp b/src/math/nvptx/sincos.cpp
index d882157b0bc8..73f92cfb7c34 100644
--- a/src/math/gpu/vendor/sincos.cpp
+++ b/src/math/nvptx/sincos.cpp
@@ -9,12 +9,12 @@
#include "src/math/sincos.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sinptr, double *cosptr)) {
- return internal::sincos(x, sinptr, cosptr);
+ return __nv_sincos(x, sinptr, cosptr);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/sincosf.cpp b/src/math/nvptx/sincosf.cpp
new file mode 100644
index 000000000000..d053aa38151b
--- /dev/null
+++ b/src/math/nvptx/sincosf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the sincosf function for GPU --------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sincosf.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinptr, float *cosptr)) {
+ return __nv_sincosf(x, sinptr, cosptr);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sinf.cpp b/src/math/nvptx/sinf.cpp
index af93227ab63b..9abd5cb4d5c6 100644
--- a/src/math/gpu/vendor/sinf.cpp
+++ b/src/math/nvptx/sinf.cpp
@@ -9,10 +9,10 @@
#include "src/math/sinf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, sinf, (float x)) { return internal::sinf(x); }
+LLVM_LIBC_FUNCTION(float, sinf, (float x)) { return __nv_sinf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sinh.cpp b/src/math/nvptx/sinh.cpp
index be6b3ae2e2fa..dc6a1e16c634 100644
--- a/src/math/gpu/vendor/sinh.cpp
+++ b/src/math/nvptx/sinh.cpp
@@ -9,10 +9,10 @@
#include "src/math/sinh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return internal::sinh(x); }
+LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return __nv_sinh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/sinhf.cpp b/src/math/nvptx/sinhf.cpp
index 99c399b62b7f..c9ab470ed823 100644
--- a/src/math/gpu/vendor/sinhf.cpp
+++ b/src/math/nvptx/sinhf.cpp
@@ -9,10 +9,10 @@
#include "src/math/sinhf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return internal::sinhf(x); }
+LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return __nv_sinhf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/sqrt.cpp b/src/math/nvptx/sqrt.cpp
new file mode 100644
index 000000000000..60ca5af4987b
--- /dev/null
+++ b/src/math/nvptx/sqrt.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU sqrt 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/sqrt.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, sqrt, (double x)) { return __builtin_sqrt(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/sqrtf.cpp b/src/math/nvptx/sqrtf.cpp
new file mode 100644
index 000000000000..e17f942a4d5f
--- /dev/null
+++ b/src/math/nvptx/sqrtf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU sqrtf 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/sqrtf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, sqrtf, (float x)) { return __builtin_sqrtf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tan.cpp b/src/math/nvptx/tan.cpp
index 9a1bd9c89fcf..deb03dca250a 100644
--- a/src/math/gpu/vendor/tan.cpp
+++ b/src/math/nvptx/tan.cpp
@@ -9,10 +9,10 @@
#include "src/math/tan.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, tan, (double x)) { return internal::tan(x); }
+LLVM_LIBC_FUNCTION(double, tan, (double x)) { return __nv_tan(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tanf.cpp b/src/math/nvptx/tanf.cpp
index a5266a8c154c..5739e4a1624d 100644
--- a/src/math/gpu/vendor/tanf.cpp
+++ b/src/math/nvptx/tanf.cpp
@@ -9,10 +9,10 @@
#include "src/math/tanf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, tanf, (float x)) { return internal::tanf(x); }
+LLVM_LIBC_FUNCTION(float, tanf, (float x)) { return __nv_tanf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tanh.cpp b/src/math/nvptx/tanh.cpp
index 57d764f1f2a0..eabee2cbaf06 100644
--- a/src/math/gpu/vendor/tanh.cpp
+++ b/src/math/nvptx/tanh.cpp
@@ -9,10 +9,10 @@
#include "src/math/tanh.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return internal::tanh(x); }
+LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return __nv_tanh(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tanhf.cpp b/src/math/nvptx/tanhf.cpp
index 1c9c2f3843a9..582424cb9490 100644
--- a/src/math/gpu/vendor/tanhf.cpp
+++ b/src/math/nvptx/tanhf.cpp
@@ -9,10 +9,10 @@
#include "src/math/tanhf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { return internal::tanhf(x); }
+LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { return __nv_tanhf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tgamma.cpp b/src/math/nvptx/tgamma.cpp
index e86116a2b0ab..f92193831f9b 100644
--- a/src/math/gpu/vendor/tgamma.cpp
+++ b/src/math/nvptx/tgamma.cpp
@@ -9,10 +9,10 @@
#include "src/math/tgamma.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, tgamma, (double x)) { return internal::tgamma(x); }
+LLVM_LIBC_FUNCTION(double, tgamma, (double x)) { return __nv_tgamma(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/gpu/vendor/tgammaf.cpp b/src/math/nvptx/tgammaf.cpp
index 552919bae446..833994455d57 100644
--- a/src/math/gpu/vendor/tgammaf.cpp
+++ b/src/math/nvptx/tgammaf.cpp
@@ -9,10 +9,10 @@
#include "src/math/tgammaf.h"
#include "src/__support/common.h"
-#include "common.h"
+#include "declarations.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, tgammaf, (float x)) { return internal::tgammaf(x); }
+LLVM_LIBC_FUNCTION(float, tgammaf, (float x)) { return __nv_tgammaf(x); }
} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/trunc.cpp b/src/math/nvptx/trunc.cpp
new file mode 100644
index 000000000000..773600f0f250
--- /dev/null
+++ b/src/math/nvptx/trunc.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU trunc 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/trunc.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, trunc, (double x)) { return __builtin_trunc(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nvptx/truncf.cpp b/src/math/nvptx/truncf.cpp
new file mode 100644
index 000000000000..534797a3e586
--- /dev/null
+++ b/src/math/nvptx/truncf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of the GPU truncf 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/truncf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, truncf, (float x)) { return __builtin_truncf(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/rintf128.h b/src/math/rintf128.h
new file mode 100644
index 000000000000..2d9248974f02
--- /dev/null
+++ b/src/math/rintf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for rintf128 ----------------------*- 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_RINTF128_H
+#define LLVM_LIBC_SRC_MATH_RINTF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 rintf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_RINTF128_H
diff --git a/src/math/roundeven.h b/src/math/roundeven.h
new file mode 100644
index 000000000000..9c76b1fe334a
--- /dev/null
+++ b/src/math/roundeven.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundeven ---------------------*- 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_ROUNDEVEN_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVEN_H
+
+namespace LIBC_NAMESPACE {
+
+double roundeven(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVEN_H
diff --git a/src/math/roundevenf.h b/src/math/roundevenf.h
new file mode 100644
index 000000000000..447e7fd940c1
--- /dev/null
+++ b/src/math/roundevenf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundevenf --------------------*- 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_ROUNDEVENF_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENF_H
+
+namespace LIBC_NAMESPACE {
+
+float roundevenf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENF_H
diff --git a/src/math/roundevenf128.h b/src/math/roundevenf128.h
new file mode 100644
index 000000000000..589839d09075
--- /dev/null
+++ b/src/math/roundevenf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundevenf128 -----------------*- 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_ROUNDEVENF128_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 roundevenf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENF128_H
diff --git a/src/math/roundevenl.h b/src/math/roundevenl.h
new file mode 100644
index 000000000000..a2f3397e4479
--- /dev/null
+++ b/src/math/roundevenl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundevenl --------------------*- 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_ROUNDEVENL_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENL_H
+
+namespace LIBC_NAMESPACE {
+
+long double roundevenl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENL_H
diff --git a/src/math/roundf128.h b/src/math/roundf128.h
new file mode 100644
index 000000000000..e4aca17d7eb6
--- /dev/null
+++ b/src/math/roundf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundf128 ---------------------*- 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_ROUNDF128_H
+#define LLVM_LIBC_SRC_MATH_ROUNDF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 roundf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDF128_H
diff --git a/src/math/sqrtf128.h b/src/math/sqrtf128.h
index bccb6bbb6332..9da9eb69374c 100644
--- a/src/math/sqrtf128.h
+++ b/src/math/sqrtf128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_MATH_SQRTF128_H
#define LLVM_LIBC_SRC_MATH_SQRTF128_H
-#include "src/__support/macros/properties/float.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE {
diff --git a/src/math/truncf128.h b/src/math/truncf128.h
new file mode 100644
index 000000000000..5eb6116551d1
--- /dev/null
+++ b/src/math/truncf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for truncf128 ---------------------*- 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_TRUNCF128_H
+#define LLVM_LIBC_SRC_MATH_TRUNCF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 truncf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_TRUNCF128_H
diff --git a/src/math/ufromfp.h b/src/math/ufromfp.h
new file mode 100644
index 000000000000..f4667486440c
--- /dev/null
+++ b/src/math/ufromfp.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfp -----------------------*- 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_UFROMFP_H
+#define LLVM_LIBC_SRC_MATH_UFROMFP_H
+
+namespace LIBC_NAMESPACE {
+
+double ufromfp(double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFP_H
diff --git a/src/math/ufromfpf.h b/src/math/ufromfpf.h
new file mode 100644
index 000000000000..40c6773d143e
--- /dev/null
+++ b/src/math/ufromfpf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfpf ----------------------*- 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_UFROMFPF_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPF_H
+
+namespace LIBC_NAMESPACE {
+
+float ufromfpf(float x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPF_H
diff --git a/src/math/ufromfpf128.h b/src/math/ufromfpf128.h
new file mode 100644
index 000000000000..785fa82becbc
--- /dev/null
+++ b/src/math/ufromfpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ufromfpf128 -------------------*- 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_UFROMFPF128_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 ufromfpf128(float128 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPF128_H
diff --git a/src/math/ufromfpl.h b/src/math/ufromfpl.h
new file mode 100644
index 000000000000..f05a77dc2f10
--- /dev/null
+++ b/src/math/ufromfpl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfpl ----------------------*- 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_UFROMFPL_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPL_H
+
+namespace LIBC_NAMESPACE {
+
+long double ufromfpl(long double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPL_H
diff --git a/src/math/ufromfpx.h b/src/math/ufromfpx.h
new file mode 100644
index 000000000000..79c413af968a
--- /dev/null
+++ b/src/math/ufromfpx.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfpx ----------------------*- 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_UFROMFPX_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPX_H
+
+namespace LIBC_NAMESPACE {
+
+double ufromfpx(double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPX_H
diff --git a/src/math/ufromfpxf.h b/src/math/ufromfpxf.h
new file mode 100644
index 000000000000..f6bd8f7d5995
--- /dev/null
+++ b/src/math/ufromfpxf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfpxf ---------------------*- 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_UFROMFPXF_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPXF_H
+
+namespace LIBC_NAMESPACE {
+
+float ufromfpxf(float x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPXF_H
diff --git a/src/math/ufromfpxf128.h b/src/math/ufromfpxf128.h
new file mode 100644
index 000000000000..f3b43ff54f37
--- /dev/null
+++ b/src/math/ufromfpxf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ufromfpxf128 ------------------*- 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_UFROMFPXF128_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPXF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 ufromfpxf128(float128 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPXF128_H
diff --git a/src/math/ufromfpxl.h b/src/math/ufromfpxl.h
new file mode 100644
index 000000000000..180b8f93d218
--- /dev/null
+++ b/src/math/ufromfpxl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ufromfpxl ---------------------*- 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_UFROMFPXL_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPXL_H
+
+namespace LIBC_NAMESPACE {
+
+long double ufromfpxl(long double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPXL_H
diff --git a/src/search/hsearch/global.h b/src/search/hsearch/global.h
index 292008cb0c80..9579195a2f3e 100644
--- a/src/search/hsearch/global.h
+++ b/src/search/hsearch/global.h
@@ -6,8 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SEARCH_HSEARCH_GLOBAL_H
+#define LLVM_LIBC_SRC_SEARCH_HSEARCH_GLOBAL_H
+
namespace LIBC_NAMESPACE {
namespace internal {
extern struct HashTable *global_hash_table;
}
} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SEARCH_HSEARCH_GLOBAL_H
diff --git a/src/search/insque.cpp b/src/search/insque.cpp
new file mode 100644
index 000000000000..7b7d7c787af1
--- /dev/null
+++ b/src/search/insque.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of insque --------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/search/insque.h"
+#include "src/__support/common.h"
+#include "src/__support/intrusive_list.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, insque, (void *elem, void *prev)) {
+ internal::IntrusiveList::insert(elem, prev);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/search/insque.h b/src/search/insque.h
new file mode 100644
index 000000000000..e0fb69ed1df7
--- /dev/null
+++ b/src/search/insque.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for insque ------------------------*- 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_SEARCH_INSQUE_H
+#define LLVM_LIBC_SRC_SEARCH_INSQUE_H
+
+#include <search.h>
+
+namespace LIBC_NAMESPACE {
+
+void insque(void *elem, void *prev);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SEARCH_INSQUE_H
diff --git a/src/search/remque.cpp b/src/search/remque.cpp
new file mode 100644
index 000000000000..f1d9859eedb5
--- /dev/null
+++ b/src/search/remque.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of remque --------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/search/remque.h"
+#include "src/__support/common.h"
+#include "src/__support/intrusive_list.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, remque, (void *elem)) {
+ internal::IntrusiveList::remove(elem);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/search/remque.h b/src/search/remque.h
new file mode 100644
index 000000000000..51f225c00474
--- /dev/null
+++ b/src/search/remque.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for remque ------------------------*- 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_SEARCH_REMQUE_H
+#define LLVM_LIBC_SRC_SEARCH_REMQUE_H
+
+#include <search.h>
+
+namespace LIBC_NAMESPACE {
+
+void remque(void *elem);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SEARCH_REMQUE_H
diff --git a/src/stdbit/stdc_bit_ceil_uc.cpp b/src/stdbit/stdc_bit_ceil_uc.cpp
new file mode 100644
index 000000000000..675ae4a0edb0
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_ceil_uc --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_ceil_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned char, stdc_bit_ceil_uc, (unsigned char value)) {
+ return cpp::bit_ceil(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_ceil_uc.h b/src/stdbit/stdc_bit_ceil_uc.h
new file mode 100644
index 000000000000..204261e41081
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_ceil_uc --------------*- 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_STDBIT_STDC_BIT_CEIL_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned char stdc_bit_ceil_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UC_H
diff --git a/src/stdbit/stdc_bit_ceil_ui.cpp b/src/stdbit/stdc_bit_ceil_ui.cpp
new file mode 100644
index 000000000000..a8ac9726179b
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_ceil_ui --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_ceil_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_ceil_ui, (unsigned value)) {
+ return cpp::bit_ceil(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_ceil_ui.h b/src/stdbit/stdc_bit_ceil_ui.h
new file mode 100644
index 000000000000..db66c336e366
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_ceil_ui --------------*- 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_STDBIT_STDC_BIT_CEIL_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_ceil_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UI_H
diff --git a/src/stdbit/stdc_bit_ceil_ul.cpp b/src/stdbit/stdc_bit_ceil_ul.cpp
new file mode 100644
index 000000000000..18a9c38b5b4c
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_ceil_ul --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_ceil_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long, stdc_bit_ceil_ul, (unsigned long value)) {
+ return cpp::bit_ceil(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_ceil_ul.h b/src/stdbit/stdc_bit_ceil_ul.h
new file mode 100644
index 000000000000..f8393a42fcbf
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_ceil_ul --------------*- 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_STDBIT_STDC_BIT_CEIL_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned long stdc_bit_ceil_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_UL_H
diff --git a/src/stdbit/stdc_bit_ceil_ull.cpp b/src/stdbit/stdc_bit_ceil_ull.cpp
new file mode 100644
index 000000000000..0989f36ab768
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_bit_ceil_ull -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_ceil_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long long, stdc_bit_ceil_ull,
+ (unsigned long long value)) {
+ return cpp::bit_ceil(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_ceil_ull.h b/src/stdbit/stdc_bit_ceil_ull.h
new file mode 100644
index 000000000000..e65f537efb17
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_ceil_ull -------------*- 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_STDBIT_STDC_BIT_CEIL_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned long long stdc_bit_ceil_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_ULL_H
diff --git a/src/stdbit/stdc_bit_ceil_us.cpp b/src/stdbit/stdc_bit_ceil_us.cpp
new file mode 100644
index 000000000000..f86a216bb840
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_ceil_us --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_ceil_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short, stdc_bit_ceil_us, (unsigned short value)) {
+ return cpp::bit_ceil(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_ceil_us.h b/src/stdbit/stdc_bit_ceil_us.h
new file mode 100644
index 000000000000..16a14e51b743
--- /dev/null
+++ b/src/stdbit/stdc_bit_ceil_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_ceil_us --------------*- 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_STDBIT_STDC_BIT_CEIL_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned short stdc_bit_ceil_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_CEIL_US_H
diff --git a/src/stdbit/stdc_bit_floor_uc.cpp b/src/stdbit/stdc_bit_floor_uc.cpp
new file mode 100644
index 000000000000..6cb04c9eb43e
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_floor_uc -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_floor_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned char, stdc_bit_floor_uc, (unsigned char value)) {
+ return cpp::bit_floor(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_floor_uc.h b/src/stdbit/stdc_bit_floor_uc.h
new file mode 100644
index 000000000000..d6f53c5f6997
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_floor_uc -------------*- 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_STDBIT_STDC_BIT_FLOOR_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned char stdc_bit_floor_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UC_H
diff --git a/src/stdbit/stdc_bit_floor_ui.cpp b/src/stdbit/stdc_bit_floor_ui.cpp
new file mode 100644
index 000000000000..149b63f190cf
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_floor_ui -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_floor_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_floor_ui, (unsigned value)) {
+ return cpp::bit_floor(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_floor_ui.h b/src/stdbit/stdc_bit_floor_ui.h
new file mode 100644
index 000000000000..fcc606386f86
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_floor_ui -------------*- 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_STDBIT_STDC_BIT_FLOOR_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_floor_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UI_H
diff --git a/src/stdbit/stdc_bit_floor_ul.cpp b/src/stdbit/stdc_bit_floor_ul.cpp
new file mode 100644
index 000000000000..a29a04454568
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_floor_ul -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_floor_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long, stdc_bit_floor_ul, (unsigned long value)) {
+ return cpp::bit_floor(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_floor_ul.h b/src/stdbit/stdc_bit_floor_ul.h
new file mode 100644
index 000000000000..08327aa60c90
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_floor_ul -------------*- 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_STDBIT_STDC_BIT_FLOOR_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned long stdc_bit_floor_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_UL_H
diff --git a/src/stdbit/stdc_bit_floor_ull.cpp b/src/stdbit/stdc_bit_floor_ull.cpp
new file mode 100644
index 000000000000..d1084b635732
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_bit_floor_ull ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_floor_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long long, stdc_bit_floor_ull,
+ (unsigned long long value)) {
+ return cpp::bit_floor(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_floor_ull.h b/src/stdbit/stdc_bit_floor_ull.h
new file mode 100644
index 000000000000..8f360b23855a
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_floor_ull ------------*- 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_STDBIT_STDC_BIT_FLOOR_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned long long stdc_bit_floor_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_ULL_H
diff --git a/src/stdbit/stdc_bit_floor_us.cpp b/src/stdbit/stdc_bit_floor_us.cpp
new file mode 100644
index 000000000000..d1357a980e3a
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_floor_us -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_floor_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short, stdc_bit_floor_us, (unsigned short value)) {
+ return cpp::bit_floor(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_floor_us.h b/src/stdbit/stdc_bit_floor_us.h
new file mode 100644
index 000000000000..fcd0b9e3c549
--- /dev/null
+++ b/src/stdbit/stdc_bit_floor_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_floor_us -------------*- 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_STDBIT_STDC_BIT_FLOOR_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned short stdc_bit_floor_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_FLOOR_US_H
diff --git a/src/stdbit/stdc_bit_width_uc.cpp b/src/stdbit/stdc_bit_width_uc.cpp
new file mode 100644
index 000000000000..2c361c1bbb1c
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_width_uc -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_width_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_width_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::bit_width(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_width_uc.h b/src/stdbit/stdc_bit_width_uc.h
new file mode 100644
index 000000000000..70c038aaf1df
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_width_uc -------------*- 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_STDBIT_STDC_BIT_WIDTH_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_width_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UC_H
diff --git a/src/stdbit/stdc_bit_width_ui.cpp b/src/stdbit/stdc_bit_width_ui.cpp
new file mode 100644
index 000000000000..b94452b09bd5
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_width_ui -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_width_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_width_ui, (unsigned value)) {
+ return static_cast<unsigned>(cpp::bit_width(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_width_ui.h b/src/stdbit/stdc_bit_width_ui.h
new file mode 100644
index 000000000000..9e8de3d6ef46
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_width_ui -------------*- 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_STDBIT_STDC_BIT_WIDTH_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_width_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UI_H
diff --git a/src/stdbit/stdc_bit_width_ul.cpp b/src/stdbit/stdc_bit_width_ul.cpp
new file mode 100644
index 000000000000..80044314e4b2
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_width_ul -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_width_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_width_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::bit_width(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_width_ul.h b/src/stdbit/stdc_bit_width_ul.h
new file mode 100644
index 000000000000..447a2918e2f2
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_width_ul -------------*- 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_STDBIT_STDC_BIT_WIDTH_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_width_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_UL_H
diff --git a/src/stdbit/stdc_bit_width_ull.cpp b/src/stdbit/stdc_bit_width_ull.cpp
new file mode 100644
index 000000000000..006fa20b2de5
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ull.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_width_ull ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_width_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_width_ull, (unsigned long long value)) {
+ return static_cast<unsigned>(cpp::bit_width(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_width_ull.h b/src/stdbit/stdc_bit_width_ull.h
new file mode 100644
index 000000000000..bc51897f448f
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_width_ull ------------*- 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_STDBIT_STDC_BIT_WIDTH_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_width_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_ULL_H
diff --git a/src/stdbit/stdc_bit_width_us.cpp b/src/stdbit/stdc_bit_width_us.cpp
new file mode 100644
index 000000000000..3d9f72bf5d06
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_bit_width_us -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_bit_width_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_bit_width_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::bit_width(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_bit_width_us.h b/src/stdbit/stdc_bit_width_us.h
new file mode 100644
index 000000000000..02cd37426eb4
--- /dev/null
+++ b/src/stdbit/stdc_bit_width_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_bit_width_us -------------*- 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_STDBIT_STDC_BIT_WIDTH_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_bit_width_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_BIT_WIDTH_US_H
diff --git a/src/stdbit/stdc_count_ones_uc.cpp b/src/stdbit/stdc_count_ones_uc.cpp
new file mode 100644
index 000000000000..1e998ff521b7
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_ones_uc ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_ones_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_ones_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::popcount(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_ones_uc.h b/src/stdbit/stdc_count_ones_uc.h
new file mode 100644
index 000000000000..eed3ee5f181b
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_ones_uc -----------*- 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_STDBIT_STDC_COUNT_ONES_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_ones_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UC_H
diff --git a/src/stdbit/stdc_count_ones_ui.cpp b/src/stdbit/stdc_count_ones_ui.cpp
new file mode 100644
index 000000000000..e457dd793db3
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_ones_ui ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_ones_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_ones_ui, (unsigned value)) {
+ return static_cast<unsigned>(cpp::popcount(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_ones_ui.h b/src/stdbit/stdc_count_ones_ui.h
new file mode 100644
index 000000000000..1f7ccb9c502f
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_ones_ui -----------*- 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_STDBIT_STDC_COUNT_ONES_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_ones_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UI_H
diff --git a/src/stdbit/stdc_count_ones_ul.cpp b/src/stdbit/stdc_count_ones_ul.cpp
new file mode 100644
index 000000000000..ed86653fc7ee
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_ones_ul ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_ones_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_ones_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::popcount(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/__support/OSUtil/gpu/quick_exit.h b/src/stdbit/stdc_count_ones_ul.h
index b51385defbc0..bde349a2fb94 100644
--- a/src/__support/OSUtil/gpu/quick_exit.h
+++ b/src/stdbit/stdc_count_ones_ul.h
@@ -1,4 +1,4 @@
-//===---------- GPU implementation of a quick exit function -----*- C++ -*-===//
+//===-- Implementation header for stdc_count_ones_ul -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
-#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
+#ifndef LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UL_H
namespace LIBC_NAMESPACE {
-void quick_exit(int status);
+unsigned stdc_count_ones_ul(unsigned long value);
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_GPU_QUICK_EXIT_H
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_UL_H
diff --git a/src/stdbit/stdc_count_ones_ull.cpp b/src/stdbit/stdc_count_ones_ull.cpp
new file mode 100644
index 000000000000..c5ecc3cda647
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_ull.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_ones_ull -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_ones_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_ones_ull, (unsigned long long value)) {
+ return static_cast<unsigned>(cpp::popcount(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_ones_ull.h b/src/stdbit/stdc_count_ones_ull.h
new file mode 100644
index 000000000000..830239f8874b
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_ones_ull -----------*- 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_STDBIT_STDC_COUNT_ONES_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_ones_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_ULL_H
diff --git a/src/stdbit/stdc_count_ones_us.cpp b/src/stdbit/stdc_count_ones_us.cpp
new file mode 100644
index 000000000000..465c5c374e7c
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_ones_us ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_ones_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_ones_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::popcount(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_ones_us.h b/src/stdbit/stdc_count_ones_us.h
new file mode 100644
index 000000000000..08fd4e76eaae
--- /dev/null
+++ b/src/stdbit/stdc_count_ones_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_ones_us -----------*- 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_STDBIT_STDC_COUNT_ONES_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_ones_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ONES_US_H
diff --git a/src/stdbit/stdc_count_zeros_uc.cpp b/src/stdbit/stdc_count_zeros_uc.cpp
new file mode 100644
index 000000000000..309ebb55e0fa
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_zeros_uc -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_zeros_uc.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_uc, (unsigned char value)) {
+ return static_cast<unsigned>(count_zeros(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_zeros_uc.h b/src/stdbit/stdc_count_zeros_uc.h
new file mode 100644
index 000000000000..34b4636ee3f9
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_zeros_uc -----------*- 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_STDBIT_STDC_COUNT_ZEROS_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_zeros_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UC_H
diff --git a/src/stdbit/stdc_count_zeros_ui.cpp b/src/stdbit/stdc_count_zeros_ui.cpp
new file mode 100644
index 000000000000..31ea907b24de
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_zeros_ui -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_zeros_ui.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ui, (unsigned value)) {
+ return static_cast<unsigned>(count_zeros(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_zeros_ui.h b/src/stdbit/stdc_count_zeros_ui.h
new file mode 100644
index 000000000000..48e8630f6f09
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_zeros_ui -----------*- 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_STDBIT_STDC_COUNT_ZEROS_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_zeros_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UI_H
diff --git a/src/stdbit/stdc_count_zeros_ul.cpp b/src/stdbit/stdc_count_zeros_ul.cpp
new file mode 100644
index 000000000000..f5df5c49f131
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_zeros_ul -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_zeros_ul.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ul, (unsigned long value)) {
+ return static_cast<unsigned>(count_zeros(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_zeros_ul.h b/src/stdbit/stdc_count_zeros_ul.h
new file mode 100644
index 000000000000..b88387741ade
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_zeros_ul -----------*- 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_STDBIT_STDC_COUNT_ZEROS_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_zeros_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_UL_H
diff --git a/src/stdbit/stdc_count_zeros_ull.cpp b/src/stdbit/stdc_count_zeros_ull.cpp
new file mode 100644
index 000000000000..6a9c8f04a799
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ull.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_zeros_ull ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_zeros_ull.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ull, (unsigned long long value)) {
+ return static_cast<unsigned>(count_zeros(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_zeros_ull.h b/src/stdbit/stdc_count_zeros_ull.h
new file mode 100644
index 000000000000..e15b33011ab7
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_zeros_ull ----------*- 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_STDBIT_STDC_COUNT_ZEROS_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_zeros_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_ULL_H
diff --git a/src/stdbit/stdc_count_zeros_us.cpp b/src/stdbit/stdc_count_zeros_us.cpp
new file mode 100644
index 000000000000..c08186ec6e87
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_count_zeros_us -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_count_zeros_us.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_us, (unsigned short value)) {
+ return static_cast<unsigned>(count_zeros(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_count_zeros_us.h b/src/stdbit/stdc_count_zeros_us.h
new file mode 100644
index 000000000000..d422377f076b
--- /dev/null
+++ b/src/stdbit/stdc_count_zeros_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_count_zeros_us -----------*- 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_STDBIT_STDC_COUNT_ZEROS_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_count_zeros_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_COUNT_ZEROS_US_H
diff --git a/src/stdbit/stdc_first_leading_one_uc.cpp b/src/stdbit/stdc_first_leading_one_uc.cpp
new file mode 100644
index 000000000000..2e28ed3bb6f8
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_leading_one_uc -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_one_uc.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_uc, (unsigned char value)) {
+ return static_cast<unsigned>(first_leading_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_one_uc.h b/src/stdbit/stdc_first_leading_one_uc.h
new file mode 100644
index 000000000000..58892c3f0ff2
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_one_uc -----*- 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_STDBIT_STDC_FIRST_LEADING_ONE_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_one_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UC_H
diff --git a/src/stdbit/stdc_first_leading_one_ui.cpp b/src/stdbit/stdc_first_leading_one_ui.cpp
new file mode 100644
index 000000000000..a07a39b09d9f
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_leading_one_ui -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_one_ui.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ui, (unsigned value)) {
+ return static_cast<unsigned>(first_leading_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_one_ui.h b/src/stdbit/stdc_first_leading_one_ui.h
new file mode 100644
index 000000000000..613adf4e1ff7
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_one_ui -----*- 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_STDBIT_STDC_FIRST_LEADING_ONE_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_one_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UI_H
diff --git a/src/stdbit/stdc_first_leading_one_ul.cpp b/src/stdbit/stdc_first_leading_one_ul.cpp
new file mode 100644
index 000000000000..4350fb7826b4
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_leading_one_ul -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_one_ul.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ul, (unsigned long value)) {
+ return static_cast<unsigned>(first_leading_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_one_ul.h b/src/stdbit/stdc_first_leading_one_ul.h
new file mode 100644
index 000000000000..47c179f3fbac
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_one_ul -----*- 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_STDBIT_STDC_FIRST_LEADING_ONE_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_one_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_UL_H
diff --git a/src/stdbit/stdc_first_leading_one_ull.cpp b/src/stdbit/stdc_first_leading_one_ull.cpp
new file mode 100644
index 000000000000..57a5ae368e11
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_one_ull ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_one_ull.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(first_leading_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_one_ull.h b/src/stdbit/stdc_first_leading_one_ull.h
new file mode 100644
index 000000000000..344d03f7100f
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_one_ull ----*- 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_STDBIT_STDC_FIRST_LEADING_ONE_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_one_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_ULL_H
diff --git a/src/stdbit/stdc_first_leading_one_us.cpp b/src/stdbit/stdc_first_leading_one_us.cpp
new file mode 100644
index 000000000000..f14433b13f35
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_us.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_one_us -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_one_us.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_us,
+ (unsigned short value)) {
+ return static_cast<unsigned>(first_leading_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_one_us.h b/src/stdbit/stdc_first_leading_one_us.h
new file mode 100644
index 000000000000..9d5feaf1e92f
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_one_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_one_us -----*- 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_STDBIT_STDC_FIRST_LEADING_ONE_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_one_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ONE_US_H
diff --git a/src/stdbit/stdc_first_leading_zero_uc.cpp b/src/stdbit/stdc_first_leading_zero_uc.cpp
new file mode 100644
index 000000000000..6e2164256f17
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_uc.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_zero_uc ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_zero_uc.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_uc,
+ (unsigned char value)) {
+ return static_cast<unsigned>(first_leading_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_zero_uc.h b/src/stdbit/stdc_first_leading_zero_uc.h
new file mode 100644
index 000000000000..63ecd20acc61
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_zero_uc ----*- 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_STDBIT_STDC_FIRST_LEADING_ZERO_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_zero_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UC_H
diff --git a/src/stdbit/stdc_first_leading_zero_ui.cpp b/src/stdbit/stdc_first_leading_zero_ui.cpp
new file mode 100644
index 000000000000..cb733a94c0d8
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_leading_zero_ui ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_zero_ui.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ui, (unsigned value)) {
+ return static_cast<unsigned>(first_leading_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_zero_ui.h b/src/stdbit/stdc_first_leading_zero_ui.h
new file mode 100644
index 000000000000..d8d5d9345010
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_zero_ui ----*- 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_STDBIT_STDC_FIRST_LEADING_ZERO_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_zero_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UI_H
diff --git a/src/stdbit/stdc_first_leading_zero_ul.cpp b/src/stdbit/stdc_first_leading_zero_ul.cpp
new file mode 100644
index 000000000000..8a3930a271ed
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ul.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_zero_ul ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_zero_ul.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ul,
+ (unsigned long value)) {
+ return static_cast<unsigned>(first_leading_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_zero_ul.h b/src/stdbit/stdc_first_leading_zero_ul.h
new file mode 100644
index 000000000000..8df1b55c2c3a
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_zero_ul ----*- 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_STDBIT_STDC_FIRST_LEADING_ZERO_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_zero_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_UL_H
diff --git a/src/stdbit/stdc_first_leading_zero_ull.cpp b/src/stdbit/stdc_first_leading_zero_ull.cpp
new file mode 100644
index 000000000000..5a69197a8299
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_zero_ull ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_zero_ull.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(first_leading_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_zero_ull.h b/src/stdbit/stdc_first_leading_zero_ull.h
new file mode 100644
index 000000000000..9aec5e7e5545
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_zero_ull ---*- 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_STDBIT_STDC_FIRST_LEADING_ZERO_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_zero_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_ULL_H
diff --git a/src/stdbit/stdc_first_leading_zero_us.cpp b/src/stdbit/stdc_first_leading_zero_us.cpp
new file mode 100644
index 000000000000..6482c8654db3
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_us.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_leading_zero_us ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_leading_zero_us.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_us,
+ (unsigned short value)) {
+ return static_cast<unsigned>(first_leading_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_leading_zero_us.h b/src/stdbit/stdc_first_leading_zero_us.h
new file mode 100644
index 000000000000..8587378069ce
--- /dev/null
+++ b/src/stdbit/stdc_first_leading_zero_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_leading_zero_us ----*- 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_STDBIT_STDC_FIRST_LEADING_ZERO_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_leading_zero_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_LEADING_ZERO_US_H
diff --git a/src/stdbit/stdc_first_trailing_one_uc.cpp b/src/stdbit/stdc_first_trailing_one_uc.cpp
new file mode 100644
index 000000000000..d3e8825eef00
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_uc.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_one_uc ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_one_uc.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_one_uc,
+ (unsigned char value)) {
+ return static_cast<unsigned>(first_trailing_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_one_uc.h b/src/stdbit/stdc_first_trailing_one_uc.h
new file mode 100644
index 000000000000..d733ce850de0
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_one_uc ---*- 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_STDBIT_STDC_FIRST_TRAILING_ONE_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_one_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UC_H
diff --git a/src/stdbit/stdc_first_trailing_one_ui.cpp b/src/stdbit/stdc_first_trailing_one_ui.cpp
new file mode 100644
index 000000000000..842bd6995050
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_trailing_one_ui ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_one_ui.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_one_ui, (unsigned value)) {
+ return static_cast<unsigned>(first_trailing_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_one_ui.h b/src/stdbit/stdc_first_trailing_one_ui.h
new file mode 100644
index 000000000000..6a6a5046709a
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_one_ui ---*- 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_STDBIT_STDC_FIRST_TRAILING_ONE_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_one_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UI_H
diff --git a/src/stdbit/stdc_first_trailing_one_ul.cpp b/src/stdbit/stdc_first_trailing_one_ul.cpp
new file mode 100644
index 000000000000..0497d1d77811
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ul.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_one_ul ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_one_ul.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_one_ul,
+ (unsigned long value)) {
+ return static_cast<unsigned>(first_trailing_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_one_ul.h b/src/stdbit/stdc_first_trailing_one_ul.h
new file mode 100644
index 000000000000..09b6a9bbbe34
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_one_ul ---*- 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_STDBIT_STDC_FIRST_TRAILING_ONE_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_one_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_UL_H
diff --git a/src/stdbit/stdc_first_trailing_one_ull.cpp b/src/stdbit/stdc_first_trailing_one_ull.cpp
new file mode 100644
index 000000000000..6e062dd27cdd
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_one_ull ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_one_ull.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_one_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(first_trailing_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_one_ull.h b/src/stdbit/stdc_first_trailing_one_ull.h
new file mode 100644
index 000000000000..3e12a1d74566
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_one_ull --*- 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_STDBIT_STDC_FIRST_TRAILING_ONE_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_one_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_ULL_H
diff --git a/src/stdbit/stdc_first_trailing_one_us.cpp b/src/stdbit/stdc_first_trailing_one_us.cpp
new file mode 100644
index 000000000000..e90158f10204
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_us.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_one_us ----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_one_us.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_one_us,
+ (unsigned short value)) {
+ return static_cast<unsigned>(first_trailing_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_one_us.h b/src/stdbit/stdc_first_trailing_one_us.h
new file mode 100644
index 000000000000..f380898fc68c
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_one_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_one_us ---*- 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_STDBIT_STDC_FIRST_TRAILING_ONE_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_one_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ONE_US_H
diff --git a/src/stdbit/stdc_first_trailing_zero_uc.cpp b/src/stdbit/stdc_first_trailing_zero_uc.cpp
new file mode 100644
index 000000000000..a6939f6286b3
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_uc.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_zero_uc ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_zero_uc.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_zero_uc,
+ (unsigned char value)) {
+ return static_cast<unsigned>(first_trailing_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_zero_uc.h b/src/stdbit/stdc_first_trailing_zero_uc.h
new file mode 100644
index 000000000000..242472ae34f2
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_zero_uc ---*- 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_STDBIT_STDC_FIRST_TRAILING_ZERO_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_zero_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UC_H
diff --git a/src/stdbit/stdc_first_trailing_zero_ui.cpp b/src/stdbit/stdc_first_trailing_zero_ui.cpp
new file mode 100644
index 000000000000..7a50b696afff
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_first_trailing_zero_ui ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_zero_ui.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_zero_ui, (unsigned value)) {
+ return static_cast<unsigned>(first_trailing_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_zero_ui.h b/src/stdbit/stdc_first_trailing_zero_ui.h
new file mode 100644
index 000000000000..cc308f762b2b
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_zero_ui ---*- 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_STDBIT_STDC_FIRST_TRAILING_ZERO_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_zero_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UI_H
diff --git a/src/stdbit/stdc_first_trailing_zero_ul.cpp b/src/stdbit/stdc_first_trailing_zero_ul.cpp
new file mode 100644
index 000000000000..88acbabdf2d9
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ul.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_zero_ul ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_zero_ul.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_zero_ul,
+ (unsigned long value)) {
+ return static_cast<unsigned>(first_trailing_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_zero_ul.h b/src/stdbit/stdc_first_trailing_zero_ul.h
new file mode 100644
index 000000000000..824133733417
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_zero_ul ---*- 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_STDBIT_STDC_FIRST_TRAILING_ZERO_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_zero_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_UL_H
diff --git a/src/stdbit/stdc_first_trailing_zero_ull.cpp b/src/stdbit/stdc_first_trailing_zero_ull.cpp
new file mode 100644
index 000000000000..92df8f284e8b
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_zero_ull --------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_zero_ull.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_zero_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(first_trailing_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_zero_ull.h b/src/stdbit/stdc_first_trailing_zero_ull.h
new file mode 100644
index 000000000000..3737fc1be2d4
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_zero_ull --*- 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_STDBIT_STDC_FIRST_TRAILING_ZERO_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_zero_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_ULL_H
diff --git a/src/stdbit/stdc_first_trailing_zero_us.cpp b/src/stdbit/stdc_first_trailing_zero_us.cpp
new file mode 100644
index 000000000000..86caa20dd3bd
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_us.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_first_trailing_zero_us ---------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_first_trailing_zero_us.h"
+
+#include "src/__support/common.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_first_trailing_zero_us,
+ (unsigned short value)) {
+ return static_cast<unsigned>(first_trailing_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_first_trailing_zero_us.h b/src/stdbit/stdc_first_trailing_zero_us.h
new file mode 100644
index 000000000000..608b05229696
--- /dev/null
+++ b/src/stdbit/stdc_first_trailing_zero_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_first_trailing_zero_us ---*- 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_STDBIT_STDC_FIRST_TRAILING_ZERO_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_first_trailing_zero_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_FIRST_TRAILING_ZERO_US_H
diff --git a/src/stdbit/stdc_has_single_bit_uc.cpp b/src/stdbit/stdc_has_single_bit_uc.cpp
new file mode 100644
index 000000000000..e5acdc2a71b4
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_has_single_bit_uc --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_has_single_bit_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(bool, stdc_has_single_bit_uc, (unsigned char value)) {
+ return cpp::has_single_bit(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_has_single_bit_uc.h b/src/stdbit/stdc_has_single_bit_uc.h
new file mode 100644
index 000000000000..028d4ee71050
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_has_single_bit_uc --------*- 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_STDBIT_STDC_HAS_SINGLE_BIT_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UC_H
+
+namespace LIBC_NAMESPACE {
+
+bool stdc_has_single_bit_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UC_H
diff --git a/src/stdbit/stdc_has_single_bit_ui.cpp b/src/stdbit/stdc_has_single_bit_ui.cpp
new file mode 100644
index 000000000000..37578882324a
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_has_single_bit_ui --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_has_single_bit_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(bool, stdc_has_single_bit_ui, (unsigned value)) {
+ return cpp::has_single_bit(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_has_single_bit_ui.h b/src/stdbit/stdc_has_single_bit_ui.h
new file mode 100644
index 000000000000..1e8cd9afaee8
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_has_single_bit_ui --------*- 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_STDBIT_STDC_HAS_SINGLE_BIT_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UI_H
+
+namespace LIBC_NAMESPACE {
+
+bool stdc_has_single_bit_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UI_H
diff --git a/src/stdbit/stdc_has_single_bit_ul.cpp b/src/stdbit/stdc_has_single_bit_ul.cpp
new file mode 100644
index 000000000000..85133ab81cc6
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_has_single_bit_ul --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_has_single_bit_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(bool, stdc_has_single_bit_ul, (unsigned long value)) {
+ return cpp::has_single_bit(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_has_single_bit_ul.h b/src/stdbit/stdc_has_single_bit_ul.h
new file mode 100644
index 000000000000..9b924fca9f06
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_has_single_bit_ul --------*- 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_STDBIT_STDC_HAS_SINGLE_BIT_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UL_H
+
+namespace LIBC_NAMESPACE {
+
+bool stdc_has_single_bit_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_UL_H
diff --git a/src/stdbit/stdc_has_single_bit_ull.cpp b/src/stdbit/stdc_has_single_bit_ull.cpp
new file mode 100644
index 000000000000..4491cf2b98b6
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ull.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_has_single_bit_ull -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_has_single_bit_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(bool, stdc_has_single_bit_ull, (unsigned long long value)) {
+ return cpp::has_single_bit(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_has_single_bit_ull.h b/src/stdbit/stdc_has_single_bit_ull.h
new file mode 100644
index 000000000000..d4802bc28727
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_has_single_bit_ull -------*- 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_STDBIT_STDC_HAS_SINGLE_BIT_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+bool stdc_has_single_bit_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_ULL_H
diff --git a/src/stdbit/stdc_has_single_bit_us.cpp b/src/stdbit/stdc_has_single_bit_us.cpp
new file mode 100644
index 000000000000..7a42ae553aa2
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_has_single_bit_us --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_has_single_bit_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(bool, stdc_has_single_bit_us, (unsigned short value)) {
+ return cpp::has_single_bit(value);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_has_single_bit_us.h b/src/stdbit/stdc_has_single_bit_us.h
new file mode 100644
index 000000000000..201ff4954c3b
--- /dev/null
+++ b/src/stdbit/stdc_has_single_bit_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_has_single_bit_us --------*- 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_STDBIT_STDC_HAS_SINGLE_BIT_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_US_H
+
+namespace LIBC_NAMESPACE {
+
+bool stdc_has_single_bit_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_HAS_SINGLE_BIT_US_H
diff --git a/src/stdbit/stdc_leading_ones_uc.cpp b/src/stdbit/stdc_leading_ones_uc.cpp
new file mode 100644
index 000000000000..69322d957dbf
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_leading_ones_uc ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_leading_ones_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::countl_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_ones_uc.h b/src/stdbit/stdc_leading_ones_uc.h
new file mode 100644
index 000000000000..fc4d2bdf623a
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_leading_ones_uc ----------*- 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_STDBIT_STDC_LEADING_ONES_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_leading_ones_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UC_H
diff --git a/src/stdbit/stdc_leading_ones_ui.cpp b/src/stdbit/stdc_leading_ones_ui.cpp
new file mode 100644
index 000000000000..2a73c2ccfa49
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_leading_ones_ui ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_leading_ones_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_ui, (unsigned value)) {
+ return static_cast<unsigned>(cpp::countl_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_ones_ui.h b/src/stdbit/stdc_leading_ones_ui.h
new file mode 100644
index 000000000000..c381eb50e973
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_leading_ones_ui ----------*- 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_STDBIT_STDC_LEADING_ONES_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_leading_ones_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UI_H
diff --git a/src/stdbit/stdc_leading_ones_ul.cpp b/src/stdbit/stdc_leading_ones_ul.cpp
new file mode 100644
index 000000000000..5b2f61d43b02
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_leading_ones_ul ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_leading_ones_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::countl_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_ones_ul.h b/src/stdbit/stdc_leading_ones_ul.h
new file mode 100644
index 000000000000..3441edf86136
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_leading_ones_ul ----------*- 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_STDBIT_STDC_LEADING_ONES_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_leading_ones_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UL_H
diff --git a/src/stdbit/stdc_leading_ones_ull.cpp b/src/stdbit/stdc_leading_ones_ull.cpp
new file mode 100644
index 000000000000..05660b9fed65
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_leading_ones_ull ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_leading_ones_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(cpp::countl_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_ones_ull.h b/src/stdbit/stdc_leading_ones_ull.h
new file mode 100644
index 000000000000..167eb732794d
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_leading_ones_ull ---------*- 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_STDBIT_STDC_LEADING_ONES_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_leading_ones_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_ULL_H
diff --git a/src/stdbit/stdc_leading_ones_us.cpp b/src/stdbit/stdc_leading_ones_us.cpp
new file mode 100644
index 000000000000..d93327db739b
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_leading_ones_us ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_leading_ones_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::countl_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_ones_us.h b/src/stdbit/stdc_leading_ones_us.h
new file mode 100644
index 000000000000..2a552d784b19
--- /dev/null
+++ b/src/stdbit/stdc_leading_ones_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_leading_ones_us ----------*- 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_STDBIT_STDC_LEADING_ONES_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_leading_ones_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_US_H
diff --git a/src/stdbit/stdc_leading_zeros_uc.cpp b/src/stdbit/stdc_leading_zeros_uc.cpp
index 8c27043e055b..dbd2d7662c44 100644
--- a/src/stdbit/stdc_leading_zeros_uc.cpp
+++ b/src/stdbit/stdc_leading_zeros_uc.cpp
@@ -13,9 +13,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(unsigned char, stdc_leading_zeros_uc,
- (unsigned char value)) {
- return static_cast<unsigned char>(cpp::countl_zero(value));
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_zeros_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::countl_zero(value));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_uc.h b/src/stdbit/stdc_leading_zeros_uc.h
index 0622e72b0683..1edca66e1344 100644
--- a/src/stdbit/stdc_leading_zeros_uc.h
+++ b/src/stdbit/stdc_leading_zeros_uc.h
@@ -11,7 +11,7 @@
namespace LIBC_NAMESPACE {
-unsigned char stdc_leading_zeros_uc(unsigned char value);
+unsigned stdc_leading_zeros_uc(unsigned char value);
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_ul.cpp b/src/stdbit/stdc_leading_zeros_ul.cpp
index cf21ff449a8b..0d5ff886fe99 100644
--- a/src/stdbit/stdc_leading_zeros_ul.cpp
+++ b/src/stdbit/stdc_leading_zeros_ul.cpp
@@ -13,9 +13,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(unsigned long, stdc_leading_zeros_ul,
- (unsigned long value)) {
- return static_cast<unsigned long>(cpp::countl_zero(value));
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_zeros_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::countl_zero(value));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_ul.h b/src/stdbit/stdc_leading_zeros_ul.h
index a1f36299931d..5bac6df1b14d 100644
--- a/src/stdbit/stdc_leading_zeros_ul.h
+++ b/src/stdbit/stdc_leading_zeros_ul.h
@@ -11,7 +11,7 @@
namespace LIBC_NAMESPACE {
-unsigned long stdc_leading_zeros_ul(unsigned long value);
+unsigned stdc_leading_zeros_ul(unsigned long value);
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_ull.cpp b/src/stdbit/stdc_leading_zeros_ull.cpp
index d488559bbd14..b23cea7c3ee4 100644
--- a/src/stdbit/stdc_leading_zeros_ull.cpp
+++ b/src/stdbit/stdc_leading_zeros_ull.cpp
@@ -13,9 +13,9 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(unsigned long long, stdc_leading_zeros_ull,
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_zeros_ull,
(unsigned long long value)) {
- return static_cast<unsigned long long>(cpp::countl_zero(value));
+ return static_cast<unsigned>(cpp::countl_zero(value));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_ull.h b/src/stdbit/stdc_leading_zeros_ull.h
index b05855b296af..e13624345fc7 100644
--- a/src/stdbit/stdc_leading_zeros_ull.h
+++ b/src/stdbit/stdc_leading_zeros_ull.h
@@ -11,7 +11,7 @@
namespace LIBC_NAMESPACE {
-unsigned long long stdc_leading_zeros_ull(unsigned long long value);
+unsigned stdc_leading_zeros_ull(unsigned long long value);
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_us.cpp b/src/stdbit/stdc_leading_zeros_us.cpp
index 84df2b842d69..424fdc728256 100644
--- a/src/stdbit/stdc_leading_zeros_us.cpp
+++ b/src/stdbit/stdc_leading_zeros_us.cpp
@@ -13,9 +13,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(unsigned short, stdc_leading_zeros_us,
- (unsigned short value)) {
- return static_cast<unsigned short>(cpp::countl_zero(value));
+LLVM_LIBC_FUNCTION(unsigned, stdc_leading_zeros_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::countl_zero(value));
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_leading_zeros_us.h b/src/stdbit/stdc_leading_zeros_us.h
index c0f62e2be2f0..6a3969002daf 100644
--- a/src/stdbit/stdc_leading_zeros_us.h
+++ b/src/stdbit/stdc_leading_zeros_us.h
@@ -11,7 +11,7 @@
namespace LIBC_NAMESPACE {
-unsigned short stdc_leading_zeros_us(unsigned short value);
+unsigned stdc_leading_zeros_us(unsigned short value);
} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_uc.cpp b/src/stdbit/stdc_trailing_ones_uc.cpp
new file mode 100644
index 000000000000..eabb21367e28
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_ones_uc ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_ones_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_ones_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::countr_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_uc.h b/src/stdbit/stdc_trailing_ones_uc.h
new file mode 100644
index 000000000000..9736e21e1f28
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_ones_uc --------*- 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_STDBIT_STDC_TRAILING_ONES_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_ones_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UC_H
diff --git a/src/stdbit/stdc_trailing_ones_ui.cpp b/src/stdbit/stdc_trailing_ones_ui.cpp
new file mode 100644
index 000000000000..87eb54fe5f02
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_ones_ui ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_ones_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_ones_ui, (unsigned value)) {
+ return static_cast<unsigned>(cpp::countr_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_ui.h b/src/stdbit/stdc_trailing_ones_ui.h
new file mode 100644
index 000000000000..aad7fcf0daf5
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_ones_ui --------*- 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_STDBIT_STDC_TRAILING_ONES_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_ones_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UI_H
diff --git a/src/stdbit/stdc_trailing_ones_ul.cpp b/src/stdbit/stdc_trailing_ones_ul.cpp
new file mode 100644
index 000000000000..6d358a21ac33
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_ones_ul ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_ones_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_ones_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::countr_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_ul.h b/src/stdbit/stdc_trailing_ones_ul.h
new file mode 100644
index 000000000000..80589501b1ed
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_ones_ul --------*- 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_STDBIT_STDC_TRAILING_ONES_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_ones_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_UL_H
diff --git a/src/stdbit/stdc_trailing_ones_ull.cpp b/src/stdbit/stdc_trailing_ones_ull.cpp
new file mode 100644
index 000000000000..fb5fffe07817
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_trailing_ones_ull --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_ones_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_ones_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(cpp::countr_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_ull.h b/src/stdbit/stdc_trailing_ones_ull.h
new file mode 100644
index 000000000000..3d3f0b306789
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_ones_ull --------*- 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_STDBIT_STDC_TRAILING_ONES_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_ones_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_ULL_H
diff --git a/src/stdbit/stdc_trailing_ones_us.cpp b/src/stdbit/stdc_trailing_ones_us.cpp
new file mode 100644
index 000000000000..ee7ff4f78d48
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_ones_us ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_ones_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_ones_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::countr_one(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_ones_us.h b/src/stdbit/stdc_trailing_ones_us.h
new file mode 100644
index 000000000000..b783cd22ad2d
--- /dev/null
+++ b/src/stdbit/stdc_trailing_ones_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_ones_us --------*- 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_STDBIT_STDC_TRAILING_ONES_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_ones_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ONES_US_H
diff --git a/src/stdbit/stdc_trailing_zeros_uc.cpp b/src/stdbit/stdc_trailing_zeros_uc.cpp
new file mode 100644
index 000000000000..36924c5a053a
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_uc.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_zeros_uc --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_zeros_uc.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_zeros_uc, (unsigned char value)) {
+ return static_cast<unsigned>(cpp::countr_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_zeros_uc.h b/src/stdbit/stdc_trailing_zeros_uc.h
new file mode 100644
index 000000000000..866201e5acea
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_uc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_zeros_uc --------*- 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_STDBIT_STDC_TRAILING_ZEROS_UC_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UC_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_zeros_uc(unsigned char value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UC_H
diff --git a/src/stdbit/stdc_trailing_zeros_ui.cpp b/src/stdbit/stdc_trailing_zeros_ui.cpp
new file mode 100644
index 000000000000..a264fd97f251
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ui.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_zeros_ui --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_zeros_ui.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_zeros_ui, (unsigned value)) {
+ return static_cast<unsigned>(cpp::countr_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_zeros_ui.h b/src/stdbit/stdc_trailing_zeros_ui.h
new file mode 100644
index 000000000000..0642e312f4fe
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ui.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_zeros_ui --------*- 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_STDBIT_STDC_TRAILING_ZEROS_UI_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UI_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_zeros_ui(unsigned value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UI_H
diff --git a/src/stdbit/stdc_trailing_zeros_ul.cpp b/src/stdbit/stdc_trailing_zeros_ul.cpp
new file mode 100644
index 000000000000..8e0c36cb0996
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ul.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_zeros_ul --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_zeros_ul.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_zeros_ul, (unsigned long value)) {
+ return static_cast<unsigned>(cpp::countr_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_zeros_ul.h b/src/stdbit/stdc_trailing_zeros_ul.h
new file mode 100644
index 000000000000..e10b4474753a
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ul.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_zeros_ul --------*- 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_STDBIT_STDC_TRAILING_ZEROS_UL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_zeros_ul(unsigned long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_UL_H
diff --git a/src/stdbit/stdc_trailing_zeros_ull.cpp b/src/stdbit/stdc_trailing_zeros_ull.cpp
new file mode 100644
index 000000000000..77cb20cb1ba4
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of stdc_trailing_zeros_ull -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_zeros_ull.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_zeros_ull,
+ (unsigned long long value)) {
+ return static_cast<unsigned>(cpp::countr_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_zeros_ull.h b/src/stdbit/stdc_trailing_zeros_ull.h
new file mode 100644
index 000000000000..f95169d29f45
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_ull.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_zeros_ull -------*- 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_STDBIT_STDC_TRAILING_ZEROS_ULL_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_ULL_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_zeros_ull(unsigned long long value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_ULL_H
diff --git a/src/stdbit/stdc_trailing_zeros_us.cpp b/src/stdbit/stdc_trailing_zeros_us.cpp
new file mode 100644
index 000000000000..a5b9f4a7d849
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_us.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of stdc_trailing_zeros_us --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdbit/stdc_trailing_zeros_us.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned, stdc_trailing_zeros_us, (unsigned short value)) {
+ return static_cast<unsigned>(cpp::countr_zero(value));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdbit/stdc_trailing_zeros_us.h b/src/stdbit/stdc_trailing_zeros_us.h
new file mode 100644
index 000000000000..ddbdf0d647ab
--- /dev/null
+++ b/src/stdbit/stdc_trailing_zeros_us.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for stdc_trailing_zeros_us --------*- 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_STDBIT_STDC_TRAILING_ZEROS_US_H
+#define LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_US_H
+
+namespace LIBC_NAMESPACE {
+
+unsigned stdc_trailing_zeros_us(unsigned short value);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDBIT_STDC_TRAILING_ZEROS_US_H
diff --git a/src/stdfix/abshk.cpp b/src/stdfix/abshk.cpp
new file mode 100644
index 000000000000..d76a5e64e610
--- /dev/null
+++ b/src/stdfix/abshk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of abshk 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 "abshk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(short accum, abshk, (short accum x)) {
+ return fixed_point::abs(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/abshk.h b/src/stdfix/abshk.h
new file mode 100644
index 000000000000..13c9300caab8
--- /dev/null
+++ b/src/stdfix/abshk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for abshk -------------------------*- 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_STDFIX_ABSHK_H
+#define LLVM_LIBC_SRC_STDFIX_ABSHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+short accum abshk(short accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSHK_H
diff --git a/src/stdfix/abshr.cpp b/src/stdfix/abshr.cpp
new file mode 100644
index 000000000000..db887046b662
--- /dev/null
+++ b/src/stdfix/abshr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of abshr 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 "abshr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(short fract, abshr, (short fract x)) {
+ return fixed_point::abs(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/abshr.h b/src/stdfix/abshr.h
new file mode 100644
index 000000000000..5acd0cfc4a60
--- /dev/null
+++ b/src/stdfix/abshr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for abshr -------------------------*- 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_STDFIX_ABSHR_H
+#define LLVM_LIBC_SRC_STDFIX_ABSHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+short fract abshr(short fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSHR_H
diff --git a/src/stdfix/absk.cpp b/src/stdfix/absk.cpp
new file mode 100644
index 000000000000..ca231d95a0ab
--- /dev/null
+++ b/src/stdfix/absk.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of absk 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 "absk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(accum, absk, (accum x)) { return fixed_point::abs(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/absk.h b/src/stdfix/absk.h
new file mode 100644
index 000000000000..73dfcac0ac8e
--- /dev/null
+++ b/src/stdfix/absk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for absk --------------------------*- 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_STDFIX_ABSK_H
+#define LLVM_LIBC_SRC_STDFIX_ABSK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+accum absk(accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSK_H
diff --git a/src/stdfix/abslk.cpp b/src/stdfix/abslk.cpp
new file mode 100644
index 000000000000..5e085198ce42
--- /dev/null
+++ b/src/stdfix/abslk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of abslk 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 "abslk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long accum, abslk, (long accum x)) {
+ return fixed_point::abs(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/abslk.h b/src/stdfix/abslk.h
new file mode 100644
index 000000000000..7de116fa2279
--- /dev/null
+++ b/src/stdfix/abslk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for abslk -------------------------*- 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_STDFIX_ABSLK_H
+#define LLVM_LIBC_SRC_STDFIX_ABSLK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+long accum abslk(long accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSLK_H
diff --git a/src/stdfix/abslr.cpp b/src/stdfix/abslr.cpp
new file mode 100644
index 000000000000..0f8969510a50
--- /dev/null
+++ b/src/stdfix/abslr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of abslr 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 "abslr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long fract, abslr, (long fract x)) {
+ return fixed_point::abs(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/abslr.h b/src/stdfix/abslr.h
new file mode 100644
index 000000000000..bf5b585bbbb6
--- /dev/null
+++ b/src/stdfix/abslr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for abslr -------------------------*- 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_STDFIX_ABSLR_H
+#define LLVM_LIBC_SRC_STDFIX_ABSLR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+long fract abslr(long fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSLR_H
diff --git a/src/stdfix/absr.cpp b/src/stdfix/absr.cpp
new file mode 100644
index 000000000000..dbbecb4947da
--- /dev/null
+++ b/src/stdfix/absr.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of absr 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 "absr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(fract, absr, (fract x)) { return fixed_point::abs(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/absr.h b/src/stdfix/absr.h
new file mode 100644
index 000000000000..b5ead7ce14e2
--- /dev/null
+++ b/src/stdfix/absr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for absr --------------------------*- 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_STDFIX_ABSR_H
+#define LLVM_LIBC_SRC_STDFIX_ABSR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+fract absr(fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ABSR_H
diff --git a/src/stdfix/exphk.cpp b/src/stdfix/exphk.cpp
new file mode 100644
index 000000000000..19a972b390c7
--- /dev/null
+++ b/src/stdfix/exphk.cpp
@@ -0,0 +1,92 @@
+//===-- Implementation of exphk 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 "exphk.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+namespace {
+
+// Look up tables for exp(hi) and exp(mid).
+// Generated with Sollya:
+// > for i from 0 to 89 do {
+// hi = floor(i/8) - 5;
+// m = i/8 - floor(i/8) - 0.5;
+// e_hi = nearestint(exp(hi) * 2^7) * 2^-7;
+// e_mid = nearestint(exp(m) * 2^7) * 2^-7;
+// print(hi, e_hi, m, e_mid);
+// };
+// Notice that when i = 88 and 89, e_hi will overflow short accum range.
+static constexpr short accum EXP_HI[12] = {
+ 0x1.0p-7hk, 0x1.0p-6hk, 0x1.8p-5hk, 0x1.1p-3hk, 0x1.78p-2hk, 0x1.0p0hk,
+ 0x1.5cp1hk, 0x1.d9p2hk, 0x1.416p4hk, 0x1.b4dp5hk, 0x1.28d4p7hk, SACCUM_MAX,
+};
+
+static constexpr short accum EXP_MID[8] = {
+ 0x1.38p-1hk, 0x1.6p-1hk, 0x1.9p-1hk, 0x1.c4p-1hk,
+ 0x1.0p0hk, 0x1.22p0hk, 0x1.48p0hk, 0x1.74p0hk,
+};
+
+} // anonymous namespace
+
+LLVM_LIBC_FUNCTION(short accum, exphk, (short accum x)) {
+ using FXRep = fixed_point::FXRep<short accum>;
+ using StorageType = typename FXRep::StorageType;
+ // Output overflow
+ if (LIBC_UNLIKELY(x >= 0x1.64p2hk))
+ return FXRep::MAX();
+ // Lower bound where exp(x) -> 0:
+ // floor(log(2^-8) * 2^7) * 2^-7
+ if (LIBC_UNLIKELY(x <= -0x1.63p2hk))
+ return FXRep::ZERO();
+
+ // Current range of x:
+ // -0x1.628p2 <= x <= 0x1.638p2
+ // Range reduction:
+ // x = hi + mid + lo,
+ // where:
+ // hi is an integer
+ // mid * 2^3 is an integer
+ // |lo| <= 2^-4.
+ // Then exp(x) = exp(hi + mid + lo) = exp(hi) * exp(mid) * exp(lo)
+ // ~ exp(hi) * exp(mid) * (1 + lo)
+ // with relative errors < |lo|^2 <= 2^-8.
+ // exp(hi) and exp(mid) are extracted from small lookup tables.
+
+ // Round-to-nearest 1/8, tie-to-(+Int):
+ constexpr short accum ONE_SIXTEENTH = 0x1.0p-4hk;
+ // x_rounded = floor(x + 1/16).
+ short accum x_rounded = ((x + ONE_SIXTEENTH) >> (FXRep::FRACTION_LEN - 3))
+ << (FXRep::FRACTION_LEN - 3);
+ short accum lo = x - x_rounded;
+
+ // Range of x_rounded:
+ // x_rounded >= floor((-0x1.628p2 + 0x1.0p-4) * 2^3) * 2^-3
+ // = -0x1.6p2 = -5.5
+ // To get the indices, we shift the values so that it start with 0.
+ // Range of indices: 0 <= indices <= 89
+ StorageType indices = cpp::bit_cast<StorageType>((x_rounded + 0x1.6p2hk) >>
+ (FXRep::FRACTION_LEN - 3));
+ // So we have the following relation:
+ // indices = (hi + mid + 44/8) * 8
+ // That implies:
+ // hi + mid = indices/8 - 5.5
+ // So for lookup tables, we can use the upper 4 bits to get:
+ // exp( floor(indices / 8) - 5 )
+ // and lower 3 bits for:
+ // exp( (indices - floor(indices)) - 0.5 )
+ short accum exp_hi = EXP_HI[indices >> 3];
+ short accum exp_mid = EXP_MID[indices & 0x7];
+ // exp(x) ~ exp(hi) * exp(mid) * (1 + lo);
+ return (exp_hi * (exp_mid * (0x1.0p0hk + lo)));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/exphk.h b/src/stdfix/exphk.h
new file mode 100644
index 000000000000..da03bb76d53f
--- /dev/null
+++ b/src/stdfix/exphk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for exphk -------------------------*- 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_STDFIX_EXPHK_H
+#define LLVM_LIBC_SRC_STDFIX_EXPHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+short accum exphk(short accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_EXPHK_H
diff --git a/src/stdfix/expk.cpp b/src/stdfix/expk.cpp
new file mode 100644
index 000000000000..57227fd27769
--- /dev/null
+++ b/src/stdfix/expk.cpp
@@ -0,0 +1,104 @@
+//===-- Implementation of expk 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 "expk.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+namespace {
+
+// Look up tables for exp(hi) and exp(mid).
+// Generated with Sollya:
+// > for i from 0 to 23 do {
+// hi = i - 11;
+// e_hi = nearestint(exp(hi) * 2^15) * 2^-15;
+// print(e_hi, "k,");
+// };
+static constexpr accum EXP_HI[24] = {
+ 0x1p-15k, 0x1p-15k, 0x1p-13k, 0x1.6p-12k,
+ 0x1.ep-11k, 0x1.44p-9k, 0x1.bap-8k, 0x1.2cp-6k,
+ 0x1.97cp-5k, 0x1.153p-3k, 0x1.78b8p-2k, 0x1p0k,
+ 0x1.5bf1p1k, 0x1.d8e68p2k, 0x1.415e6p4k, 0x1.b4c9p5k,
+ 0x1.28d388p7k, 0x1.936dc6p8k, 0x1.1228858p10k, 0x1.749ea7cp11k,
+ 0x1.fa7157cp12k, 0x1.5829dcf8p14k, 0x1.d3c4489p15k, ACCUM_MAX,
+};
+
+// Generated with Sollya:
+// > for i from 0 to 15 do {
+// m = i/16 - 0.0625;
+// e_m = nearestint(exp(m) * 2^15) * 2^-15;
+// print(e_m, "k,");
+// };
+static constexpr accum EXP_MID[16] = {
+ 0x1.e0fcp-1k, 0x1p0k, 0x1.1082p0k, 0x1.2216p0k,
+ 0x1.34ccp0k, 0x1.48b6p0k, 0x1.5deap0k, 0x1.747ap0k,
+ 0x1.8c8p0k, 0x1.a612p0k, 0x1.c14cp0k, 0x1.de46p0k,
+ 0x1.fd1ep0k, 0x1.0efap1k, 0x1.2074p1k, 0x1.330ep1k,
+};
+
+} // anonymous namespace
+
+LLVM_LIBC_FUNCTION(accum, expk, (accum x)) {
+ using FXRep = fixed_point::FXRep<accum>;
+ using StorageType = typename FXRep::StorageType;
+ // Output overflow
+ // > floor(log(2^16) * 2^15) * 2^-15
+ if (LIBC_UNLIKELY(x >= 0x1.62e4p3k))
+ return FXRep::MAX();
+ // Lower bound where exp(x) -> 0:
+ // floor(log(2^-16) * 2^15) * 2^-15
+ if (LIBC_UNLIKELY(x <= -0x1.62e44p3k))
+ return FXRep::ZERO();
+
+ // Current range of x:
+ // -0x1.62e4p3 <= x <= 0x1.62e3cp3
+ // Range reduction:
+ // x = hi + mid + lo,
+ // where:
+ // hi is an integer
+ // mid * 2^4 is an integer
+ // |lo| <= 2^-5.
+ // Then exp(x) = exp(hi + mid + lo) = exp(hi) * exp(mid) * exp(lo)
+ // ~ exp(hi) * exp(mid) * (1 + lo + lo^2 / 2)
+ // with relative errors < |lo|^3/2 <= 2^-16.
+ // exp(hi) and exp(mid) are extracted from small lookup tables.
+
+ // Round-to-nearest 1/16, tie-to-(+Int):
+ constexpr accum ONE_THIRTY_SECOND = 0x1.0p-5k;
+ // x_rounded = floor(x + 1/16).
+ accum x_rounded = ((x + ONE_THIRTY_SECOND) >> (FXRep::FRACTION_LEN - 4))
+ << (FXRep::FRACTION_LEN - 4);
+ accum lo = x - x_rounded;
+
+ // Range of x_rounded:
+ // x_rounded >= floor((-0x1.62e4p3 + 0x1.0p-5) * 2^4) * 2^-4
+ // = -0x1.62p3 = -11.0625
+ // To get the indices, we shift the values so that it start with 0.
+ // Range of indices: 0 <= indices <= 355.
+ StorageType indices = cpp::bit_cast<StorageType>((x_rounded + 0x1.62p3k) >>
+ (FXRep::FRACTION_LEN - 4));
+ // So we have the following relation:
+ // indices = (hi + mid + 177/16) * 16
+ // That implies:
+ // hi + mid = indices/16 - 11.0625
+ // So for lookup tables, we can use the upper 4 bits to get:
+ // exp( floor(indices / 16) - 11 )
+ // and lower 4 bits for:
+ // exp( (indices - floor(indices)) - 0.0625 )
+ accum exp_hi = EXP_HI[indices >> 4];
+ accum exp_mid = EXP_MID[indices & 0xf];
+ // exp(x) ~ exp(hi) * exp(mid) * (1 + lo);
+ accum l1 = 0x1.0p0k + (lo >> 1); // = 1 + lo / 2
+ accum l2 = 0x1.0p0k + lo * l1; // = 1 + lo * (1 + lo / 2) = 1 + lo + lo^2/2
+ return (exp_hi * (exp_mid * l2));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/expk.h b/src/stdfix/expk.h
new file mode 100644
index 000000000000..4526686a200b
--- /dev/null
+++ b/src/stdfix/expk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for expk --------------------------*- 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_STDFIX_EXPK_H
+#define LLVM_LIBC_SRC_STDFIX_EXPK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+accum expk(accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_EXPK_H
diff --git a/src/stdfix/roundhk.cpp b/src/stdfix/roundhk.cpp
new file mode 100644
index 000000000000..a4f459ea0d65
--- /dev/null
+++ b/src/stdfix/roundhk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundhk 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 "roundhk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(short accum, roundhk, (short accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundhk.h b/src/stdfix/roundhk.h
new file mode 100644
index 000000000000..9a5c874cc030
--- /dev/null
+++ b/src/stdfix/roundhk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundhk -----------------------*- 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_STDFIX_ROUNDHK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+short accum roundhk(short accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDHK_H
diff --git a/src/stdfix/roundhr.cpp b/src/stdfix/roundhr.cpp
new file mode 100644
index 000000000000..7757d1cc735f
--- /dev/null
+++ b/src/stdfix/roundhr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundhr 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 "roundhr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(short fract, roundhr, (short fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundhr.h b/src/stdfix/roundhr.h
new file mode 100644
index 000000000000..ba5a67945d6c
--- /dev/null
+++ b/src/stdfix/roundhr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundhr -----------------------*- 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_STDFIX_ROUNDHR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+short fract roundhr(short fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDHR_H
diff --git a/src/stdfix/roundk.cpp b/src/stdfix/roundk.cpp
new file mode 100644
index 000000000000..bf47dd9898d8
--- /dev/null
+++ b/src/stdfix/roundk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundk 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 "roundk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(accum, roundk, (accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundk.h b/src/stdfix/roundk.h
new file mode 100644
index 000000000000..e9fa6d8f9c3b
--- /dev/null
+++ b/src/stdfix/roundk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundk ------------------------*- 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_STDFIX_ROUNDK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+accum roundk(accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDK_H
diff --git a/src/stdfix/roundlk.cpp b/src/stdfix/roundlk.cpp
new file mode 100644
index 000000000000..d2ffe8ab0378
--- /dev/null
+++ b/src/stdfix/roundlk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundlk 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 "roundlk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long accum, roundlk, (long accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundlk.h b/src/stdfix/roundlk.h
new file mode 100644
index 000000000000..5fa0e90e855a
--- /dev/null
+++ b/src/stdfix/roundlk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundlk -----------------------*- 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_STDFIX_ROUNDLK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDLK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+long accum roundlk(long accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDLK_H
diff --git a/src/stdfix/roundlr.cpp b/src/stdfix/roundlr.cpp
new file mode 100644
index 000000000000..cd4c911ffe68
--- /dev/null
+++ b/src/stdfix/roundlr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundlr 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 "roundlr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long fract, roundlr, (long fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundlr.h b/src/stdfix/roundlr.h
new file mode 100644
index 000000000000..c015292e8f3f
--- /dev/null
+++ b/src/stdfix/roundlr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundlr -----------------------*- 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_STDFIX_ROUNDLR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDLR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+long fract roundlr(long fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDLR_H
diff --git a/src/stdfix/roundr.cpp b/src/stdfix/roundr.cpp
new file mode 100644
index 000000000000..24216936d5f9
--- /dev/null
+++ b/src/stdfix/roundr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundr 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 "roundr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(fract, roundr, (fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundr.h b/src/stdfix/roundr.h
new file mode 100644
index 000000000000..b5b1375c882e
--- /dev/null
+++ b/src/stdfix/roundr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundr ------------------------*- 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_STDFIX_ROUNDR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+fract roundr(fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDR_H
diff --git a/src/stdfix/rounduhk.cpp b/src/stdfix/rounduhk.cpp
new file mode 100644
index 000000000000..22561588e033
--- /dev/null
+++ b/src/stdfix/rounduhk.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of rounduhk 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 "rounduhk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short accum, rounduhk,
+ (unsigned short accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/rounduhk.h b/src/stdfix/rounduhk.h
new file mode 100644
index 000000000000..85ebf2903ec7
--- /dev/null
+++ b/src/stdfix/rounduhk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for rounduhk ----------------------*- 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_STDFIX_ROUNDUHK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDUHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned short accum rounduhk(unsigned short accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDUHK_H
diff --git a/src/stdfix/rounduhr.cpp b/src/stdfix/rounduhr.cpp
new file mode 100644
index 000000000000..e2e3435c15ef
--- /dev/null
+++ b/src/stdfix/rounduhr.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of rounduhr 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 "rounduhr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short fract, rounduhr,
+ (unsigned short fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/rounduhr.h b/src/stdfix/rounduhr.h
new file mode 100644
index 000000000000..1be0aab1f5a7
--- /dev/null
+++ b/src/stdfix/rounduhr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for rounduhr ----------------------*- 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_STDFIX_ROUNDUHR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDUHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned short fract rounduhr(unsigned short fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDUHR_H
diff --git a/src/stdfix/rounduk.cpp b/src/stdfix/rounduk.cpp
new file mode 100644
index 000000000000..b9f8522aed35
--- /dev/null
+++ b/src/stdfix/rounduk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of rounduk 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 "rounduk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned accum, rounduk, (unsigned accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/rounduk.h b/src/stdfix/rounduk.h
new file mode 100644
index 000000000000..8dae89586c49
--- /dev/null
+++ b/src/stdfix/rounduk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for rounduk -----------------------*- 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_STDFIX_ROUNDUK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDUK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned accum rounduk(unsigned accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDUK_H
diff --git a/src/stdfix/roundulk.cpp b/src/stdfix/roundulk.cpp
new file mode 100644
index 000000000000..241b2c2c9a06
--- /dev/null
+++ b/src/stdfix/roundulk.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of roundulk 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 "roundulk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long accum, roundulk,
+ (unsigned long accum x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundulk.h b/src/stdfix/roundulk.h
new file mode 100644
index 000000000000..81dfd1dceb60
--- /dev/null
+++ b/src/stdfix/roundulk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundulk ----------------------*- 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_STDFIX_ROUNDULK_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDULK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned long accum roundulk(unsigned long accum x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDULK_H
diff --git a/src/stdfix/roundulr.cpp b/src/stdfix/roundulr.cpp
new file mode 100644
index 000000000000..6c32074520cd
--- /dev/null
+++ b/src/stdfix/roundulr.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of roundulr 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 "roundulr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long fract, roundulr,
+ (unsigned long fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundulr.h b/src/stdfix/roundulr.h
new file mode 100644
index 000000000000..002fc94907c6
--- /dev/null
+++ b/src/stdfix/roundulr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundulr ----------------------*- 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_STDFIX_ROUNDULR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDULR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned long fract roundulr(unsigned long fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDULR_H
diff --git a/src/stdfix/roundur.cpp b/src/stdfix/roundur.cpp
new file mode 100644
index 000000000000..e91b7f110375
--- /dev/null
+++ b/src/stdfix/roundur.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundur 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 "roundur.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned fract, roundur, (unsigned fract x, int n)) {
+ return fixed_point::round(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/roundur.h b/src/stdfix/roundur.h
new file mode 100644
index 000000000000..72de44b1e0c4
--- /dev/null
+++ b/src/stdfix/roundur.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundur -----------------------*- 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_STDFIX_ROUNDUR_H
+#define LLVM_LIBC_SRC_STDFIX_ROUNDUR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned fract roundur(unsigned fract x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_ROUNDUR_H
diff --git a/src/stdfix/sqrtuhk.cpp b/src/stdfix/sqrtuhk.cpp
new file mode 100644
index 000000000000..e8dc842c8a99
--- /dev/null
+++ b/src/stdfix/sqrtuhk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of sqrtuhk 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 "sqrtuhk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short accum, sqrtuhk, (unsigned short accum x)) {
+ return fixed_point::sqrt(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/sqrtuhk.h b/src/stdfix/sqrtuhk.h
new file mode 100644
index 000000000000..80000a007969
--- /dev/null
+++ b/src/stdfix/sqrtuhk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for sqrtuhk -----------------------*- 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_STDFIX_SQRTUHK_H
+#define LLVM_LIBC_SRC_STDFIX_SQRTUHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned short accum sqrtuhk(unsigned short accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_SQRTUHK_H
diff --git a/src/stdfix/sqrtuhr.cpp b/src/stdfix/sqrtuhr.cpp
new file mode 100644
index 000000000000..6bba07aa20d5
--- /dev/null
+++ b/src/stdfix/sqrtuhr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of sqrtuhr 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 "sqrtuhr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short fract, sqrtuhr, (unsigned short fract x)) {
+ return fixed_point::sqrt(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/sqrtuhr.h b/src/stdfix/sqrtuhr.h
new file mode 100644
index 000000000000..fd95f0924e8d
--- /dev/null
+++ b/src/stdfix/sqrtuhr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for sqrtuhr -----------------------*- 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_STDFIX_SQRTUHR_H
+#define LLVM_LIBC_SRC_STDFIX_SQRTUHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned short fract sqrtuhr(unsigned short fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_SQRTUHR_H
diff --git a/src/stdfix/sqrtuk.cpp b/src/stdfix/sqrtuk.cpp
new file mode 100644
index 000000000000..6e5d8118c83b
--- /dev/null
+++ b/src/stdfix/sqrtuk.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of sqrtuk 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 "sqrtuk.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned accum, sqrtuk, (unsigned accum x)) {
+ return fixed_point::sqrt(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/sqrtuk.h b/src/stdfix/sqrtuk.h
new file mode 100644
index 000000000000..04d0adadde9a
--- /dev/null
+++ b/src/stdfix/sqrtuk.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for sqrtuk ------------------------*- 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_STDFIX_SQRTUK_H
+#define LLVM_LIBC_SRC_STDFIX_SQRTUK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned accum sqrtuk(unsigned accum x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_SQRTUK_H
diff --git a/src/stdfix/sqrtulr.cpp b/src/stdfix/sqrtulr.cpp
new file mode 100644
index 000000000000..c9e5cd51f66b
--- /dev/null
+++ b/src/stdfix/sqrtulr.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of sqrtulr 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 "sqrtulr.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long fract, sqrtulr, (unsigned long fract x)) {
+ return fixed_point::sqrt(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/sqrtulr.h b/src/stdfix/sqrtulr.h
new file mode 100644
index 000000000000..284adaaf35bf
--- /dev/null
+++ b/src/stdfix/sqrtulr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for sqrtulr -----------------------*- 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_STDFIX_SQRTULR_H
+#define LLVM_LIBC_SRC_STDFIX_SQRTULR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned long fract sqrtulr(unsigned long fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_SQRTULR_H
diff --git a/src/stdfix/sqrtur.cpp b/src/stdfix/sqrtur.cpp
new file mode 100644
index 000000000000..ac5be8491084
--- /dev/null
+++ b/src/stdfix/sqrtur.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of sqrtur 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 "sqrtur.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned fract, sqrtur, (unsigned fract x)) {
+ return fixed_point::sqrt(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/sqrtur.h b/src/stdfix/sqrtur.h
new file mode 100644
index 000000000000..df9dfe5a0bf3
--- /dev/null
+++ b/src/stdfix/sqrtur.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for sqrtur ------------------------*- 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_STDFIX_SQRTUR_H
+#define LLVM_LIBC_SRC_STDFIX_SQRTUR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned fract sqrtur(unsigned fract x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_SQRTUR_H
diff --git a/src/stdfix/uhksqrtus.cpp b/src/stdfix/uhksqrtus.cpp
new file mode 100644
index 000000000000..335750ae902b
--- /dev/null
+++ b/src/stdfix/uhksqrtus.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of uhksqrtus 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 "uhksqrtus.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned short accum, uhksqrtus, (unsigned short x)) {
+#ifdef LIBC_FAST_MATH
+ return fixed_point::isqrt_fast(x);
+#else
+ return fixed_point::isqrt(x);
+#endif
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/uhksqrtus.h b/src/stdfix/uhksqrtus.h
new file mode 100644
index 000000000000..c24846a80030
--- /dev/null
+++ b/src/stdfix/uhksqrtus.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for uhksqrtus ---------------------*- 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_STDFIX_UHKSQRTUS_H
+#define LLVM_LIBC_SRC_STDFIX_UHKSQRTUS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned short accum uhksqrtus(unsigned short x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_UHKSQRTUS_H
diff --git a/src/stdfix/uksqrtui.cpp b/src/stdfix/uksqrtui.cpp
new file mode 100644
index 000000000000..ee1ae1335027
--- /dev/null
+++ b/src/stdfix/uksqrtui.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of uksqrtui 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 "uksqrtui.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned accum, uksqrtui, (unsigned int x)) {
+#ifdef LIBC_FAST_MATH
+ return fixed_point::isqrt_fast(x);
+#else
+ return fixed_point::isqrt(x);
+#endif
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdfix/uksqrtui.h b/src/stdfix/uksqrtui.h
new file mode 100644
index 000000000000..cd4ff41ea100
--- /dev/null
+++ b/src/stdfix/uksqrtui.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for uksqrtui ----------------------*- 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_STDFIX_UKSQRTUI_H
+#define LLVM_LIBC_SRC_STDFIX_UKSQRTUI_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned accum uksqrtui(unsigned int x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDFIX_UKSQRTUI_H
diff --git a/src/stdio/baremetal/remove.cpp b/src/stdio/baremetal/remove.cpp
new file mode 100644
index 000000000000..f4f2cdca7c69
--- /dev/null
+++ b/src/stdio/baremetal/remove.cpp
@@ -0,0 +1,19 @@
+//===-- Linux implementation of remove ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdio/remove.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: This is a temporary workaround for issue #85335.
+
+LLVM_LIBC_FUNCTION(int, remove, (const char *)) { return -1; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/fileno.h b/src/stdio/fileno.h
new file mode 100644
index 000000000000..d41f112226c5
--- /dev/null
+++ b/src/stdio/fileno.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of fileno --------------------------*- 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_STDIO_FILENO_H
+#define LLVM_LIBC_SRC_STDIO_FILENO_H
+
+#include "include/llvm-libc-types/FILE.h"
+
+namespace LIBC_NAMESPACE {
+
+int fileno(::FILE *f);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_FILENO_H
diff --git a/src/stdio/fseeko.h b/src/stdio/fseeko.h
new file mode 100644
index 000000000000..3202ed2f97d0
--- /dev/null
+++ b/src/stdio/fseeko.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of fseeko -------------------------*- 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_STDIO_FSEEKO_H
+#define LLVM_LIBC_SRC_STDIO_FSEEKO_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+namespace LIBC_NAMESPACE {
+
+int fseeko(::FILE *stream, off_t offset, int whence);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_FSEEKO_H
diff --git a/src/stdio/ftello.h b/src/stdio/ftello.h
new file mode 100644
index 000000000000..0fdf13ab6bdb
--- /dev/null
+++ b/src/stdio/ftello.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of ftello -------------------------*- 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_STDIO_FTELLO_H
+#define LLVM_LIBC_SRC_STDIO_FTELLO_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+namespace LIBC_NAMESPACE {
+
+off_t ftello(::FILE *f);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_FTELLO_H
diff --git a/src/stdio/generic/fileno.cpp b/src/stdio/generic/fileno.cpp
new file mode 100644
index 000000000000..663ba9266376
--- /dev/null
+++ b/src/stdio/generic/fileno.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fileno
+//-------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdio/fileno.h"
+
+#include "include/llvm-libc-types/FILE.h"
+#include "src/__support/File/file.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, fileno, (::FILE * stream)) {
+ return get_fileno(reinterpret_cast<LIBC_NAMESPACE::File *>(stream));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/generic/fseek.cpp b/src/stdio/generic/fseek.cpp
index 7666e71e699d..c5edc8d4198c 100644
--- a/src/stdio/generic/fseek.cpp
+++ b/src/stdio/generic/fseek.cpp
@@ -10,7 +10,6 @@
#include "src/__support/File/file.h"
#include "src/errno/libc_errno.h"
-#include <stdio.h>
namespace LIBC_NAMESPACE {
diff --git a/src/stdio/generic/fseeko.cpp b/src/stdio/generic/fseeko.cpp
new file mode 100644
index 000000000000..215da759937f
--- /dev/null
+++ b/src/stdio/generic/fseeko.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of fseeko ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdio/fseeko.h"
+#include "src/__support/File/file.h"
+
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, fseeko, (::FILE * stream, off_t offset, int whence)) {
+ auto result =
+ reinterpret_cast<LIBC_NAMESPACE::File *>(stream)->seek(offset, whence);
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/generic/ftell.cpp b/src/stdio/generic/ftell.cpp
index 5f7803150534..d55bad282854 100644
--- a/src/stdio/generic/ftell.cpp
+++ b/src/stdio/generic/ftell.cpp
@@ -10,7 +10,6 @@
#include "src/__support/File/file.h"
#include "src/errno/libc_errno.h"
-#include <stdio.h>
namespace LIBC_NAMESPACE {
diff --git a/src/stdio/generic/ftello.cpp b/src/stdio/generic/ftello.cpp
new file mode 100644
index 000000000000..c72e56ea6eb1
--- /dev/null
+++ b/src/stdio/generic/ftello.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of ftello ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdio/ftello.h"
+#include "src/__support/File/file.h"
+
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(off_t, ftello, (::FILE * stream)) {
+ auto result = reinterpret_cast<LIBC_NAMESPACE::File *>(stream)->tell();
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return result.value();
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/linux/rename.cpp b/src/stdio/linux/rename.cpp
new file mode 100644
index 000000000000..379a6ef3c0c8
--- /dev/null
+++ b/src/stdio/linux/rename.cpp
@@ -0,0 +1,28 @@
+//===-- Linux implementation of rename ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdio/rename.h"
+#include "include/llvm-libc-macros/linux/fcntl-macros.h"
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_renameat2, AT_FDCWD, oldpath,
+ AT_FDCWD, newpath, 0);
+
+ if (ret >= 0)
+ return 0;
+ libc_errno = -ret;
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/printf_core/converter.cpp b/src/stdio/printf_core/converter.cpp
index 74a36cbf7432..613d693c3cfc 100644
--- a/src/stdio/printf_core/converter.cpp
+++ b/src/stdio/printf_core/converter.cpp
@@ -9,6 +9,7 @@
#include "src/stdio/printf_core/converter.h"
#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/printf_config.h"
#include "src/stdio/printf_core/writer.h"
// This option allows for replacing all of the conversion functions with custom
@@ -58,6 +59,8 @@ int convert(Writer *writer, const FormatSection &to_conv) {
case 'o':
case 'x':
case 'X':
+ case 'b':
+ case 'B':
return convert_int(writer, to_conv);
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
case 'f':
@@ -73,6 +76,13 @@ int convert(Writer *writer, const FormatSection &to_conv) {
case 'G':
return convert_float_dec_auto(writer, to_conv);
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+ case 'r':
+ case 'R':
+ case 'k':
+ case 'K':
+ return convert_fixed(writer, to_conv);
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
case 'n':
return convert_write_int(writer, to_conv);
diff --git a/src/stdio/printf_core/converter_atlas.h b/src/stdio/printf_core/converter_atlas.h
index 6471f3f2955b..2189ed11a551 100644
--- a/src/stdio/printf_core/converter_atlas.h
+++ b/src/stdio/printf_core/converter_atlas.h
@@ -31,6 +31,11 @@
#include "src/stdio/printf_core/float_hex_converter.h"
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+// defines convert_fixed
+#include "src/stdio/printf_core/fixed_converter.h"
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
#include "src/stdio/printf_core/write_int_converter.h"
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
diff --git a/src/stdio/printf_core/converter_utils.h b/src/stdio/printf_core/converter_utils.h
index 54f0a870d0ac..a0e96a11be5b 100644
--- a/src/stdio/printf_core/converter_utils.h
+++ b/src/stdio/printf_core/converter_utils.h
@@ -18,7 +18,9 @@
namespace LIBC_NAMESPACE {
namespace printf_core {
-LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num, LengthModifier lm) {
+LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num,
+ LengthSpec length_spec) {
+ auto [lm, bw] = length_spec;
switch (lm) {
case LengthModifier::none:
return num & cpp::numeric_limits<unsigned int>::max();
@@ -40,6 +42,18 @@ LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num, LengthModifier lm) {
return num & cpp::numeric_limits<uintptr_t>::max();
case LengthModifier::j:
return num; // j is intmax, so no mask is necessary.
+ case LengthModifier::w:
+ case LengthModifier::wf: {
+ uintmax_t mask;
+ if (bw == 0) {
+ mask = 0;
+ } else if (bw < sizeof(uintmax_t) * CHAR_BIT) {
+ mask = (static_cast<uintmax_t>(1) << bw) - 1;
+ } else {
+ mask = UINTMAX_MAX;
+ }
+ return num & mask;
+ }
}
__builtin_unreachable();
}
@@ -51,6 +65,9 @@ LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num, LengthModifier lm) {
return result; \
}
+// This is used to represent which direction the number should be rounded.
+enum class RoundDirection { Up, Down, Even };
+
} // namespace printf_core
} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/printf_core/core_structs.h b/src/stdio/printf_core/core_structs.h
index 7634d45568ab..bfe362becad1 100644
--- a/src/stdio/printf_core/core_structs.h
+++ b/src/stdio/printf_core/core_structs.h
@@ -9,8 +9,12 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CORE_STRUCTS_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CORE_STRUCTS_H
+#include "src/__support/macros/config.h"
+
#include "src/__support/CPP/string_view.h"
+#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/stdio/printf_core/printf_config.h"
#include <inttypes.h>
#include <stddef.h>
@@ -20,7 +24,12 @@ namespace printf_core {
// These length modifiers match the length modifiers in the format string, which
// is why they are formatted differently from the rest of the file.
-enum class LengthModifier { hh, h, l, ll, j, z, t, L, none };
+enum class LengthModifier { hh, h, l, ll, j, z, t, L, w, wf, none };
+
+struct LengthSpec {
+ LengthModifier lm;
+ size_t bit_width;
+};
enum FormatFlags : uint8_t {
LEFT_JUSTIFIED = 0x01, // -
@@ -42,6 +51,7 @@ struct FormatSection {
// Format Specifier Values
FormatFlags flags = FormatFlags(0);
LengthModifier length_modifier = LengthModifier::none;
+ size_t bit_width = 0;
int min_width = 0;
int precision = -1;
@@ -64,6 +74,7 @@ struct FormatSection {
if (!((static_cast<uint8_t>(flags) ==
static_cast<uint8_t>(other.flags)) &&
(min_width == other.min_width) && (precision == other.precision) &&
+ (bit_width == other.bit_width) &&
(length_modifier == other.length_modifier) &&
(conv_name == other.conv_name)))
return false;
@@ -77,7 +88,13 @@ struct FormatSection {
}
};
-enum PrimaryType : uint8_t { Unknown = 0, Float = 1, Pointer = 2, Integer = 3 };
+enum PrimaryType : uint8_t {
+ Unknown = 0,
+ Float = 1,
+ Pointer = 2,
+ Integer = 3,
+ FixedPoint = 4,
+};
// TypeDesc stores the information about a type that is relevant to printf in
// a relatively compact manner.
@@ -95,9 +112,16 @@ template <typename T> LIBC_INLINE constexpr TypeDesc type_desc_from_type() {
} else {
constexpr bool IS_POINTER = cpp::is_pointer_v<T>;
constexpr bool IS_FLOAT = cpp::is_floating_point_v<T>;
- return TypeDesc{sizeof(T), IS_POINTER ? PrimaryType::Pointer
- : IS_FLOAT ? PrimaryType::Float
- : PrimaryType::Integer};
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+ constexpr bool IS_FIXED_POINT = cpp::is_fixed_point_v<T>;
+#else
+ constexpr bool IS_FIXED_POINT = false;
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+
+ return TypeDesc{sizeof(T), IS_POINTER ? PrimaryType::Pointer
+ : IS_FLOAT ? PrimaryType::Float
+ : IS_FIXED_POINT ? PrimaryType::FixedPoint
+ : PrimaryType::Integer};
}
}
@@ -109,6 +133,7 @@ constexpr int FILE_WRITE_ERROR = -1;
constexpr int FILE_STATUS_ERROR = -2;
constexpr int NULLPTR_WRITE_ERROR = -3;
constexpr int INT_CONVERSION_ERROR = -4;
+constexpr int FIXED_POINT_CONVERSION_ERROR = -5;
} // namespace printf_core
} // namespace LIBC_NAMESPACE
diff --git a/src/stdio/printf_core/fixed_converter.h b/src/stdio/printf_core/fixed_converter.h
new file mode 100644
index 000000000000..de69c603be6b
--- /dev/null
+++ b/src/stdio/printf_core/fixed_converter.h
@@ -0,0 +1,309 @@
+//===-- Fixed Point Converter for printf ------------------------*- 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_STDIO_PRINTF_CORE_FIXED_CONVERTER_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FIXED_CONVERTER_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/integer_to_string.h"
+#include "src/__support/libc_assert.h"
+#include "src/stdio/printf_core/converter_utils.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <inttypes.h>
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE {
+namespace printf_core {
+
+// This is just for assertions. It will be compiled out for release builds.
+LIBC_INLINE constexpr uint32_t const_ten_exp(uint32_t exponent) {
+ uint32_t result = 1;
+ LIBC_ASSERT(exponent < 11);
+ for (uint32_t i = 0; i < exponent; ++i)
+ result *= 10;
+
+ return result;
+}
+
+#define READ_FX_BITS(TYPE) \
+ do { \
+ auto fixed_bits = fixed_point::FXBits<TYPE>( \
+ fixed_point::FXRep<TYPE>::StorageType(to_conv.conv_val_raw)); \
+ integral = fixed_bits.get_integral(); \
+ fractional = fixed_bits.get_fraction(); \
+ exponent = fixed_bits.get_exponent(); \
+ is_negative = fixed_bits.get_sign(); \
+ } while (false)
+
+#define APPLY_FX_LENGTH_MODIFIER(LENGTH_MODIFIER) \
+ do { \
+ if (to_conv.conv_name == 'r') { \
+ READ_FX_BITS(LENGTH_MODIFIER fract); \
+ } else if (to_conv.conv_name == 'R') { \
+ READ_FX_BITS(unsigned LENGTH_MODIFIER fract); \
+ } else if (to_conv.conv_name == 'k') { \
+ READ_FX_BITS(LENGTH_MODIFIER accum); \
+ } else if (to_conv.conv_name == 'K') { \
+ READ_FX_BITS(unsigned LENGTH_MODIFIER accum); \
+ } else { \
+ LIBC_ASSERT(false && "Invalid conversion name passed to convert_fixed"); \
+ return FIXED_POINT_CONVERSION_ERROR; \
+ } \
+ } while (false)
+
+LIBC_INLINE int convert_fixed(Writer *writer, const FormatSection &to_conv) {
+ // Long accum should be the largest type, so we can store all the smaller
+ // numbers in things sized for it.
+ using LARep = fixed_point::FXRep<unsigned long accum>;
+ using StorageType = LARep::StorageType;
+
+ // All of the letters will be defined relative to variable a, which will be
+ // the appropriate case based on the name of the conversion. This converts any
+ // conversion name into the letter 'a' with the appropriate case.
+ const char a = (to_conv.conv_name & 32) | 'A';
+ FormatFlags flags = to_conv.flags;
+
+ bool is_negative;
+ int exponent;
+ StorageType integral;
+ StorageType fractional;
+
+ // r = fract
+ // k = accum
+ // lowercase = signed
+ // uppercase = unsigned
+ // h = short
+ // l = long
+ // any other length modifier has no effect
+
+ if (to_conv.length_modifier == LengthModifier::h) {
+ APPLY_FX_LENGTH_MODIFIER(short);
+ } else if (to_conv.length_modifier == LengthModifier::l) {
+ APPLY_FX_LENGTH_MODIFIER(long);
+ } else {
+ APPLY_FX_LENGTH_MODIFIER();
+ }
+
+ LIBC_ASSERT(static_cast<size_t>(exponent) <=
+ (sizeof(StorageType) - sizeof(uint32_t)) * CHAR_BIT &&
+ "StorageType must be large enough to hold the fractional "
+ "component multiplied by a 32 bit number.");
+
+ // If to_conv doesn't specify a precision, the precision defaults to 6.
+ const size_t precision = to_conv.precision < 0 ? 6 : to_conv.precision;
+ bool has_decimal_point =
+ (precision > 0) || ((flags & FormatFlags::ALTERNATE_FORM) != 0);
+
+ // The number of non-zero digits below the decimal point for a negative power
+ // of 2 in base 10 is equal to the magnitude of the power of 2.
+
+ // A quick proof:
+ // Let p be any positive integer.
+ // Let e = 2^(-p)
+ // Let t be a positive integer such that e * 10^t is an integer.
+ // By definition: The smallest allowed value of t must be equal to the number
+ // of non-zero digits below the decimal point in e.
+ // If we evaluate e * 10^t we get the following:
+ // e * 10^t = 2^(-p) * 10*t = 2^(-p) * 2^t * 5^t = 5^t * 2^(t-p)
+ // For 5^t * 2^(t-p) to be an integer, both exponents must be non-negative,
+ // since 5 and 2 are coprime.
+ // The smallest value of t such that t-p is non-negative is p.
+ // Therefor, the number of non-zero digits below the decimal point for a given
+ // negative power of 2 "p" is equal to the value of p.
+
+ constexpr size_t MAX_FRACTION_DIGITS = LARep::FRACTION_LEN;
+
+ char fraction_digits[MAX_FRACTION_DIGITS];
+
+ size_t valid_fraction_digits = 0;
+
+ // TODO: Factor this part out
+ while (fractional > 0) {
+ uint32_t cur_digits = 0;
+ // 10^9 is used since it's the largest power of 10 that fits in a uint32_t
+ constexpr uint32_t TEN_EXP_NINE = 1000000000;
+ constexpr size_t DIGITS_PER_BLOCK = 9;
+
+ // Multiply by 10^9, then grab the digits above the decimal point, then
+ // clear those digits in fractional.
+ fractional = fractional * TEN_EXP_NINE;
+ cur_digits = static_cast<uint32_t>(fractional >> exponent);
+ fractional = fractional % (StorageType(1) << exponent);
+
+ // we add TEN_EXP_NINE to force leading zeroes to show up, then we skip the
+ // first digit in the loop.
+ const IntegerToString<uint32_t> cur_fractional_digits(cur_digits +
+ TEN_EXP_NINE);
+ for (size_t i = 0;
+ i < DIGITS_PER_BLOCK && valid_fraction_digits < MAX_FRACTION_DIGITS;
+ ++i, ++valid_fraction_digits)
+ fraction_digits[valid_fraction_digits] =
+ cur_fractional_digits.view()[i + 1];
+
+ if (valid_fraction_digits >= MAX_FRACTION_DIGITS) {
+ LIBC_ASSERT(fractional == 0 && "If the fraction digit buffer is full, "
+ "there should be no remaining digits.");
+ /*
+ A visual explanation of what this assert is checking:
+
+ 32 digits (max for 32 bit fract)
+ +------------------------------++--+--- must be zero
+ | || |
+ 123456789012345678901234567890120000
+ | || || || |
+ +-------++-------++-------++-------+
+ 9 digit blocks
+ */
+ LIBC_ASSERT(cur_digits % const_ten_exp(
+ DIGITS_PER_BLOCK -
+ (MAX_FRACTION_DIGITS % DIGITS_PER_BLOCK)) ==
+ 0 &&
+ "Digits after the MAX_FRACTION_DIGITS should all be zero.");
+ valid_fraction_digits = MAX_FRACTION_DIGITS;
+ }
+ }
+
+ if (precision < valid_fraction_digits) {
+ // Handle rounding. Just do round to nearest, tie to even since it's
+ // unspecified.
+ RoundDirection round;
+ char first_digit_after = fraction_digits[precision];
+ if (first_digit_after > '5') {
+ round = RoundDirection::Up;
+ } else if (first_digit_after < '5') {
+ round = RoundDirection::Down;
+ } else {
+ // first_digit_after == '5'
+ // need to check the remaining digits, but default to even.
+ round = RoundDirection::Even;
+ for (size_t cur_digit_index = precision + 1;
+ cur_digit_index + 1 < valid_fraction_digits; ++cur_digit_index) {
+ if (fraction_digits[cur_digit_index] != '0') {
+ round = RoundDirection::Up;
+ break;
+ }
+ }
+ }
+
+ // If we need to actually perform rounding, do so.
+ if (round == RoundDirection::Up || round == RoundDirection::Even) {
+ bool keep_rounding = true;
+ int digit_to_round = static_cast<int>(precision) - 1;
+ for (; digit_to_round >= 0 && keep_rounding; --digit_to_round) {
+ keep_rounding = false;
+ char cur_digit = fraction_digits[digit_to_round];
+ // if the digit should not be rounded up
+ if (round == RoundDirection::Even && ((cur_digit - '0') % 2) == 0) {
+ // break out of the loop
+ break;
+ }
+ fraction_digits[digit_to_round] += 1;
+
+ // if the digit was a 9, instead replace with a 0.
+ if (cur_digit == '9') {
+ fraction_digits[digit_to_round] = '0';
+ keep_rounding = true;
+ }
+ }
+
+ // if every digit below the decimal point was rounded up but we need to
+ // keep rounding
+ if (keep_rounding &&
+ (round == RoundDirection::Up ||
+ (round == RoundDirection::Even && ((integral % 2) == 1)))) {
+ // add one to the integral portion to round it up.
+ ++integral;
+ }
+ }
+
+ valid_fraction_digits = precision;
+ }
+
+ const IntegerToString<StorageType> integral_str(integral);
+
+ // these are signed to prevent underflow due to negative values. The
+ // eventual values will always be non-negative.
+ size_t trailing_zeroes = 0;
+ int padding;
+
+ // If the precision is greater than the actual result, pad with 0s
+ if (precision > valid_fraction_digits)
+ trailing_zeroes = precision - (valid_fraction_digits);
+
+ constexpr cpp::string_view DECIMAL_POINT(".");
+
+ char sign_char = 0;
+
+ // Check if the conv name is uppercase
+ if (a == 'A') {
+ // These flags are only for signed conversions, so this removes them if the
+ // conversion is unsigned.
+ flags = FormatFlags(flags &
+ ~(FormatFlags::FORCE_SIGN | FormatFlags::SPACE_PREFIX));
+ }
+
+ if (is_negative)
+ sign_char = '-';
+ else if ((flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN)
+ sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX
+ else if ((flags & FormatFlags::SPACE_PREFIX) == FormatFlags::SPACE_PREFIX)
+ sign_char = ' ';
+
+ padding = static_cast<int>(to_conv.min_width - (sign_char > 0 ? 1 : 0) -
+ integral_str.size() -
+ static_cast<int>(has_decimal_point) -
+ valid_fraction_digits - trailing_zeroes);
+ if (padding < 0)
+ padding = 0;
+
+ if ((flags & FormatFlags::LEFT_JUSTIFIED) == FormatFlags::LEFT_JUSTIFIED) {
+ // The pattern is (sign), integral, (.), (fraction), (zeroes), (spaces)
+ if (sign_char > 0)
+ RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
+ RET_IF_RESULT_NEGATIVE(writer->write(integral_str.view()));
+ if (has_decimal_point)
+ RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
+ if (valid_fraction_digits > 0)
+ RET_IF_RESULT_NEGATIVE(
+ writer->write({fraction_digits, valid_fraction_digits}));
+ if (trailing_zeroes > 0)
+ RET_IF_RESULT_NEGATIVE(writer->write('0', trailing_zeroes));
+ if (padding > 0)
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
+ } else {
+ // The pattern is (spaces), (sign), (zeroes), integral, (.), (fraction),
+ // (zeroes)
+ if ((padding > 0) &&
+ ((flags & FormatFlags::LEADING_ZEROES) != FormatFlags::LEADING_ZEROES))
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
+ if (sign_char > 0)
+ RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
+ if ((padding > 0) &&
+ ((flags & FormatFlags::LEADING_ZEROES) == FormatFlags::LEADING_ZEROES))
+ RET_IF_RESULT_NEGATIVE(writer->write('0', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(integral_str.view()));
+ if (has_decimal_point)
+ RET_IF_RESULT_NEGATIVE(writer->write(DECIMAL_POINT));
+ if (valid_fraction_digits > 0)
+ RET_IF_RESULT_NEGATIVE(
+ writer->write({fraction_digits, valid_fraction_digits}));
+ if (trailing_zeroes > 0)
+ RET_IF_RESULT_NEGATIVE(writer->write('0', trailing_zeroes));
+ }
+ return WRITE_OK;
+}
+
+} // namespace printf_core
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FIXED_CONVERTER_H
diff --git a/src/stdio/printf_core/float_dec_converter.h b/src/stdio/printf_core/float_dec_converter.h
index b54526d37108..c4e8aaa2f0e2 100644
--- a/src/stdio/printf_core/float_dec_converter.h
+++ b/src/stdio/printf_core/float_dec_converter.h
@@ -12,6 +12,7 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/UInt.h" // is_big_int_v
#include "src/__support/float_to_string.h"
#include "src/__support/integer_to_string.h"
#include "src/__support/libc_assert.h"
@@ -33,7 +34,8 @@ using ExponentString =
// Returns true if value is divisible by 2^p.
template <typename T>
-LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T> || is_big_int_v<T>,
+ bool>
multiple_of_power_of_2(T value, uint32_t p) {
return (value & ((T(1) << p) - 1)) == 0;
}
@@ -45,11 +47,8 @@ constexpr uint32_t MAX_BLOCK = 999999999;
// constexpr uint32_t MAX_BLOCK = 999999999999999999;
constexpr char DECIMAL_POINT = '.';
-// This is used to represent which direction the number should be rounded.
-enum class RoundDirection { Up, Down, Even };
-
LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated,
- fputil::Sign sign) {
+ Sign sign) {
switch (fputil::quick_get_round()) {
case FE_TONEAREST:
// Round to nearest, if it's exactly halfway then round to even.
@@ -79,7 +78,8 @@ LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated,
}
template <typename T>
-LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_integral_v<T> || is_big_int_v<T>,
+ bool>
zero_after_digits(int32_t base_2_exp, int32_t digits_after_point, T mantissa,
const int32_t mant_width) {
const int32_t required_twos = -base_2_exp - digits_after_point - 1;
diff --git a/src/stdio/printf_core/int_converter.h b/src/stdio/printf_core/int_converter.h
index 7744d801cbc1..496e7bd1a56d 100644
--- a/src/stdio/printf_core/int_converter.h
+++ b/src/stdio/printf_core/int_converter.h
@@ -33,14 +33,17 @@ using HexFmt = IntegerToString<uintmax_t, radix::Hex>;
using HexFmtUppercase = IntegerToString<uintmax_t, radix::Hex::Uppercase>;
using OctFmt = IntegerToString<uintmax_t, radix::Oct>;
using DecFmt = IntegerToString<uintmax_t>;
+using BinFmt = IntegerToString<uintmax_t, radix::Bin>;
LIBC_INLINE constexpr size_t num_buf_size() {
- constexpr auto max = [](size_t a, size_t b) -> size_t {
- return (a < b) ? b : a;
- };
- return max(HexFmt::buffer_size(),
- max(HexFmtUppercase::buffer_size(),
- max(OctFmt::buffer_size(), DecFmt::buffer_size())));
+ cpp::array<size_t, 5> sizes{
+ HexFmt::buffer_size(), HexFmtUppercase::buffer_size(),
+ OctFmt::buffer_size(), DecFmt::buffer_size(), BinFmt::buffer_size()};
+
+ auto result = sizes[0];
+ for (size_t i = 1; i < sizes.size(); i++)
+ result = cpp::max(result, sizes[i]);
+ return result;
}
LIBC_INLINE cpp::optional<cpp::string_view>
@@ -52,6 +55,8 @@ num_to_strview(uintmax_t num, cpp::span<char> bufref, char conv_name) {
return HexFmtUppercase::format_to(bufref, num);
} else if (conv_name == 'o') {
return OctFmt::format_to(bufref, num);
+ } else if (to_lower(conv_name) == 'b') {
+ return BinFmt::format_to(bufref, num);
} else {
return DecFmt::format_to(bufref, num);
}
@@ -66,7 +71,6 @@ LIBC_INLINE int convert_int(Writer *writer, const FormatSection &to_conv) {
uintmax_t num = static_cast<uintmax_t>(to_conv.conv_val_raw);
bool is_negative = false;
FormatFlags flags = to_conv.flags;
-
const char a = is_lower(to_conv.conv_name) ? 'a' : 'A';
// If the conversion is signed, then handle negative values.
@@ -84,8 +88,8 @@ LIBC_INLINE int convert_int(Writer *writer, const FormatSection &to_conv) {
~(FormatFlags::FORCE_SIGN | FormatFlags::SPACE_PREFIX));
}
- num = apply_length_modifier(num, to_conv.length_modifier);
-
+ num =
+ apply_length_modifier(num, {to_conv.length_modifier, to_conv.bit_width});
cpp::array<char, details::num_buf_size()> buf;
auto str = details::num_to_strview(num, buf, to_conv.conv_name);
if (!str)
@@ -116,6 +120,11 @@ LIBC_INLINE int convert_int(Writer *writer, const FormatSection &to_conv) {
prefix_len = 2;
prefix[0] = '0';
prefix[1] = a + ('x' - 'a');
+ } else if ((to_lower(to_conv.conv_name) == 'b') &&
+ ((flags & FormatFlags::ALTERNATE_FORM) != 0) && num != 0) {
+ prefix_len = 2;
+ prefix[0] = '0';
+ prefix[1] = a + ('b' - 'a');
} else {
prefix_len = (sign_char == 0 ? 0 : 1);
prefix[0] = sign_char;
diff --git a/src/stdio/printf_core/parser.h b/src/stdio/printf_core/parser.h
index ab491655275f..eda978a83ea8 100644
--- a/src/stdio/printf_core/parser.h
+++ b/src/stdio/printf_core/parser.h
@@ -9,13 +9,20 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PARSER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PARSER_H
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/algorithm.h" // max
#include "src/__support/CPP/optional.h"
+#include "src/__support/CPP/type_traits.h"
#include "src/__support/str_to_integer.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/printf_config.h"
#include <stddef.h>
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+#include "src/__support/fixed_point/fx_rep.h"
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+
namespace LIBC_NAMESPACE {
namespace printf_core {
@@ -28,6 +35,14 @@ template <> struct int_type_of<double> {
template <> struct int_type_of<long double> {
using type = fputil::FPBits<long double>::StorageType;
};
+
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+template <typename T>
+struct int_type_of<cpp::enable_if<cpp::is_fixed_point_v<T>, T>> {
+ using type = typename fixed_point::FXRep<T>::StorageType;
+};
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+
template <typename T> using int_type_of_v = typename int_type_of<T>::type;
#ifndef LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
@@ -136,10 +151,10 @@ public:
}
}
- LengthModifier lm = parse_length_modifier(&cur_pos);
-
+ auto [lm, bw] = parse_length_modifier(&cur_pos);
section.length_modifier = lm;
section.conv_name = str[cur_pos];
+ section.bit_width = bw;
switch (str[cur_pos]) {
case ('%'):
// Regardless of options, a % conversion is always safe. The standard
@@ -159,6 +174,8 @@ public:
case ('x'):
case ('X'):
case ('u'):
+ case ('b'):
+ case ('B'):
switch (lm) {
case (LengthModifier::hh):
case (LengthModifier::h):
@@ -186,6 +203,21 @@ public:
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, ptrdiff_t, conv_index);
break;
+
+ case (LengthModifier::w):
+ case (LengthModifier::wf):
+ if (bw == 0) {
+ section.has_conv = false;
+ } else if (bw <= INT_WIDTH) {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, int, conv_index);
+ } else if (bw <= LONG_WIDTH) {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long, conv_index);
+ } else if (bw <= LLONG_WIDTH) {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long long, conv_index);
+ } else {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, intmax_t, conv_index);
+ }
+ break;
}
break;
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
@@ -204,6 +236,25 @@ public:
}
break;
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+ // Capitalization represents sign, but we only need to get the right
+ // bitwidth here so we ignore that.
+ case ('r'):
+ case ('R'):
+ // all fract sizes we support are less than 32 bits, and currently doing
+ // va_args with fixed point types just doesn't work.
+ // TODO: Move to fixed point types once va_args supports it.
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, uint32_t, conv_index);
+ break;
+ case ('k'):
+ case ('K'):
+ if (lm == LengthModifier::l) {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, uint64_t, conv_index);
+ } else {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, uint32_t, conv_index);
+ }
+ break;
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
case ('n'):
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
@@ -271,38 +322,54 @@ private:
// assumes that str[*local_pos] is inside a format specifier. It returns a
// LengthModifier with the length modifier it found. It will advance local_pos
// after the format specifier if one is found.
- LIBC_INLINE LengthModifier parse_length_modifier(size_t *local_pos) {
+ LIBC_INLINE LengthSpec parse_length_modifier(size_t *local_pos) {
switch (str[*local_pos]) {
case ('l'):
if (str[*local_pos + 1] == 'l') {
*local_pos += 2;
- return LengthModifier::ll;
+ return {LengthModifier::ll, 0};
+ } else {
+ ++*local_pos;
+ return {LengthModifier::l, 0};
+ }
+ case ('w'): {
+ LengthModifier lm;
+ if (str[*local_pos + 1] == 'f') {
+ *local_pos += 2;
+ lm = LengthModifier::wf;
} else {
++*local_pos;
- return LengthModifier::l;
+ lm = LengthModifier::w;
+ }
+ if (internal::isdigit(str[*local_pos])) {
+ const auto result = internal::strtointeger<int>(str + *local_pos, 10);
+ *local_pos += result.parsed_len;
+ return {lm, static_cast<size_t>(cpp::max(0, result.value))};
}
+ return {lm, 0};
+ }
case ('h'):
if (str[*local_pos + 1] == 'h') {
*local_pos += 2;
- return LengthModifier::hh;
+ return {LengthModifier::hh, 0};
} else {
++*local_pos;
- return LengthModifier::h;
+ return {LengthModifier::h, 0};
}
case ('L'):
++*local_pos;
- return LengthModifier::L;
+ return {LengthModifier::L, 0};
case ('j'):
++*local_pos;
- return LengthModifier::j;
+ return {LengthModifier::j, 0};
case ('z'):
++*local_pos;
- return LengthModifier::z;
+ return {LengthModifier::z, 0};
case ('t'):
++*local_pos;
- return LengthModifier::t;
+ return {LengthModifier::t, 0};
default:
- return LengthModifier::none;
+ return {LengthModifier::none, 0};
}
}
@@ -397,6 +464,22 @@ private:
else if (cur_type_desc == type_desc_from_type<long double>())
args_cur.template next_var<long double>();
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+ // Floating point numbers may be stored separately from the other
+ // arguments.
+ else if (cur_type_desc == type_desc_from_type<short fract>())
+ args_cur.template next_var<short fract>();
+ else if (cur_type_desc == type_desc_from_type<fract>())
+ args_cur.template next_var<fract>();
+ else if (cur_type_desc == type_desc_from_type<long fract>())
+ args_cur.template next_var<long fract>();
+ else if (cur_type_desc == type_desc_from_type<short accum>())
+ args_cur.template next_var<short accum>();
+ else if (cur_type_desc == type_desc_from_type<accum>())
+ args_cur.template next_var<accum>();
+ else if (cur_type_desc == type_desc_from_type<long accum>())
+ args_cur.template next_var<long accum>();
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
// pointers may be stored separately from normal values.
else if (cur_type_desc == type_desc_from_type<void *>())
args_cur.template next_var<void *>();
@@ -458,7 +541,7 @@ private:
}
}
- LengthModifier lm = parse_length_modifier(&local_pos);
+ auto [lm, bw] = parse_length_modifier(&local_pos);
// if we don't have an index for this conversion, then its position is
// unknown and all this information is irrelevant. The rest of this
@@ -484,6 +567,8 @@ private:
case ('x'):
case ('X'):
case ('u'):
+ case ('b'):
+ case ('B'):
switch (lm) {
case (LengthModifier::hh):
case (LengthModifier::h):
@@ -507,6 +592,18 @@ private:
case (LengthModifier::t):
conv_size = type_desc_from_type<ptrdiff_t>();
break;
+ case (LengthModifier::w):
+ case (LengthModifier::wf):
+ if (bw <= INT_WIDTH) {
+ conv_size = type_desc_from_type<int>();
+ } else if (bw <= LONG_WIDTH) {
+ conv_size = type_desc_from_type<long>();
+ } else if (bw <= LLONG_WIDTH) {
+ conv_size = type_desc_from_type<long long>();
+ } else {
+ conv_size = type_desc_from_type<intmax_t>();
+ }
+ break;
}
break;
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
@@ -524,6 +621,22 @@ private:
conv_size = type_desc_from_type<long double>();
break;
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+ // Capitalization represents sign, but we only need to get the right
+ // bitwidth here so we ignore that.
+ case ('r'):
+ case ('R'):
+ conv_size = type_desc_from_type<uint32_t>();
+ break;
+ case ('k'):
+ case ('K'):
+ if (lm == LengthModifier::l) {
+ conv_size = type_desc_from_type<uint64_t>();
+ } else {
+ conv_size = type_desc_from_type<uint32_t>();
+ }
+ break;
+#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
case ('n'):
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
diff --git a/src/stdio/printf_core/printf_config.h b/src/stdio/printf_core/printf_config.h
index e1d9654f3aff..8a48abdd170e 100644
--- a/src/stdio/printf_core/printf_config.h
+++ b/src/stdio/printf_core/printf_config.h
@@ -29,6 +29,13 @@
#define LIBC_COPT_PRINTF_INDEX_ARR_LEN 128
#endif
+// If fixed point is available and the user hasn't explicitly opted out, then
+// enable fixed point.
+#if defined(LIBC_COMPILER_HAS_FIXED_POINT) && \
+ !defined(LIBC_COPT_PRINTF_DISABLE_FIXED_POINT)
+#define LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
+#endif
+
// TODO(michaelrj): Provide a proper interface for these options.
// LIBC_COPT_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE
// LIBC_COPT_FLOAT_TO_STR_USE_DYADIC_FLOAT
diff --git a/src/stdio/printf_core/string_converter.h b/src/stdio/printf_core/string_converter.h
index 04dc5a06da22..9e05591079fa 100644
--- a/src/stdio/printf_core/string_converter.h
+++ b/src/stdio/printf_core/string_converter.h
@@ -25,7 +25,7 @@ LIBC_INLINE int convert_string(Writer *writer, const FormatSection &to_conv) {
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
if (str_ptr == nullptr) {
- str_ptr = "null";
+ str_ptr = "(null)";
}
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
diff --git a/src/stdio/printf_core/write_int_converter.h b/src/stdio/printf_core/write_int_converter.h
index 0310905f36f1..18aa5c79897e 100644
--- a/src/stdio/printf_core/write_int_converter.h
+++ b/src/stdio/printf_core/write_int_converter.h
@@ -55,6 +55,8 @@ LIBC_INLINE int convert_write_int(Writer *writer,
*reinterpret_cast<ptrdiff_t *>(to_conv.conv_val_ptr) = written;
break;
case LengthModifier::j:
+ case LengthModifier::w:
+ case LengthModifier::wf:
*reinterpret_cast<uintmax_t *>(to_conv.conv_val_ptr) = written;
break;
}
diff --git a/src/stdio/rename.h b/src/stdio/rename.h
new file mode 100644
index 000000000000..eadda7c3eac9
--- /dev/null
+++ b/src/stdio/rename.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of rename -------------------------*- 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_STDIO_RENAME_H
+#define LLVM_LIBC_SRC_STDIO_RENAME_H
+
+namespace LIBC_NAMESPACE {
+
+int rename(const char *oldpath, const char *newpath);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_RENAME_H
diff --git a/src/stdio/scanf_core/float_converter.cpp b/src/stdio/scanf_core/float_converter.cpp
index 47a43d58ba7c..8500d98f4121 100644
--- a/src/stdio/scanf_core/float_converter.cpp
+++ b/src/stdio/scanf_core/float_converter.cpp
@@ -57,8 +57,8 @@ int convert_float(Reader *reader, const FormatSection &to_conv) {
if (to_lower(cur_char) == inf_string[0]) {
size_t inf_index = 0;
- for (; to_lower(cur_char) == inf_string[inf_index] &&
- inf_index < sizeof(inf_string) && out_str.length() < max_width;
+ for (; inf_index < sizeof(inf_string) && out_str.length() < max_width &&
+ to_lower(cur_char) == inf_string[inf_index];
++inf_index) {
if (!out_str.append(cur_char)) {
return ALLOCATION_FAILURE;
@@ -80,8 +80,8 @@ int convert_float(Reader *reader, const FormatSection &to_conv) {
if (to_lower(cur_char) == nan_string[0]) {
size_t nan_index = 0;
- for (; to_lower(cur_char) == nan_string[nan_index] &&
- nan_index < sizeof(nan_string) && out_str.length() < max_width;
+ for (; nan_index < sizeof(nan_string) && out_str.length() < max_width &&
+ to_lower(cur_char) == nan_string[nan_index];
++nan_index) {
if (!out_str.append(cur_char)) {
return ALLOCATION_FAILURE;
diff --git a/src/stdlib/_Exit.cpp b/src/stdlib/_Exit.cpp
index 85684d1e9087..233af2097392 100644
--- a/src/stdlib/_Exit.cpp
+++ b/src/stdlib/_Exit.cpp
@@ -13,9 +13,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
+[[noreturn]] LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
quick_exit(status);
- __builtin_unreachable();
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/atexit.cpp b/src/stdlib/atexit.cpp
index 10dff42b1be9..fa072b2fdf8d 100644
--- a/src/stdlib/atexit.cpp
+++ b/src/stdlib/atexit.cpp
@@ -28,8 +28,15 @@ struct AtExitUnit {
constexpr AtExitUnit(AtExitCallback *c, void *p) : callback(c), payload(p) {}
};
-#ifdef LIBC_COPT_PUBLIC_PACKAGING
-using ExitCallbackList = cpp::ReverseOrderBlockStore<AtExitUnit, 32>;
+#if defined(LIBC_TARGET_ARCH_IS_GPU)
+// The GPU build cannot handle the potentially recursive definitions required by
+// the BlockStore class. Additionally, the liklihood that someone exceeds this
+// while executing on the GPU is extremely small.
+// FIXME: It is not generally safe to use 'atexit' on the GPU because the
+// mutexes simply passthrough. We will need a lock free stack.
+using ExitCallbackList = FixedVector<AtExitUnit, 64>;
+#elif defined(LIBC_COPT_PUBLIC_PACKAGING)
+using ExitCallbackList = ReverseOrderBlockStore<AtExitUnit, 32>;
#else
// BlockStore uses dynamic memory allocation. To avoid dynamic memory
// allocation in tests, we use a fixed size callback list when built for
@@ -48,14 +55,10 @@ void stdc_at_exit_func(void *payload) {
reinterpret_cast<StdCAtExitCallback *>(payload)();
}
-} // namespace
-
-namespace internal {
-
void call_exit_callbacks() {
handler_list_mtx.lock();
while (!exit_callbacks.empty()) {
- auto unit = exit_callbacks.back();
+ AtExitUnit &unit = exit_callbacks.back();
exit_callbacks.pop_back();
handler_list_mtx.unlock();
unit.callback(unit.payload);
@@ -64,20 +67,31 @@ void call_exit_callbacks() {
ExitCallbackList::destroy(&exit_callbacks);
}
-} // namespace internal
-
-static int add_atexit_unit(const AtExitUnit &unit) {
+int add_atexit_unit(const AtExitUnit &unit) {
MutexLock lock(&handler_list_mtx);
- if (!exit_callbacks.push_back(unit))
- return -1;
- return 0;
+ if (exit_callbacks.push_back(unit))
+ return 0;
+ return -1;
}
+} // namespace
+
+extern "C" {
+
// TODO: Handle the last dso handle argument.
-extern "C" int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
+int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
return add_atexit_unit({callback, payload});
}
+// TODO: Handle the dso handle argument. call_exit_callbacks should only invoke
+// the callbacks from this DSO. Requires adding support for __dso_handle.
+void __cxa_finalize(void *dso) {
+ if (!dso)
+ call_exit_callbacks();
+}
+
+} // extern "C"
+
LLVM_LIBC_FUNCTION(int, atexit, (StdCAtExitCallback * callback)) {
return add_atexit_unit(
{&stdc_at_exit_func, reinterpret_cast<void *>(callback)});
diff --git a/src/stdlib/exit.cpp b/src/stdlib/exit.cpp
index cc5ae6648d11..ba87bffaeb54 100644
--- a/src/stdlib/exit.cpp
+++ b/src/stdlib/exit.cpp
@@ -10,16 +10,13 @@
#include "src/__support/OSUtil/quick_exit.h"
#include "src/__support/common.h"
-namespace LIBC_NAMESPACE {
+extern "C" void __cxa_finalize(void *);
-namespace internal {
-void call_exit_callbacks();
-}
+namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(void, exit, (int status)) {
- internal::call_exit_callbacks();
+[[noreturn]] LLVM_LIBC_FUNCTION(void, exit, (int status)) {
+ __cxa_finalize(nullptr);
quick_exit(status);
- __builtin_unreachable();
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/gpu/free.cpp b/src/stdlib/gpu/free.cpp
index 3a41e5febad0..fb5703b78ae6 100644
--- a/src/stdlib/gpu/free.cpp
+++ b/src/stdlib/gpu/free.cpp
@@ -7,17 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/free.h"
-#include "src/__support/RPC/rpc_client.h"
+
+#include "src/__support/GPU/allocator.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(void, free, (void *ptr)) {
- rpc::Client::Port port = rpc::client.open<RPC_FREE>();
- port.send([=](rpc::Buffer *buffer) {
- buffer->data[0] = reinterpret_cast<uintptr_t>(ptr);
- });
- port.close();
-}
+LLVM_LIBC_FUNCTION(void, free, (void *ptr)) { gpu::deallocate(ptr); }
} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/gpu/malloc.cpp b/src/stdlib/gpu/malloc.cpp
index a21969078305..93558231d081 100644
--- a/src/stdlib/gpu/malloc.cpp
+++ b/src/stdlib/gpu/malloc.cpp
@@ -7,20 +7,14 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/malloc.h"
-#include "src/__support/RPC/rpc_client.h"
+
+#include "src/__support/GPU/allocator.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) {
- void *ptr = nullptr;
- rpc::Client::Port port = rpc::client.open<RPC_MALLOC>();
- port.send_and_recv([=](rpc::Buffer *buffer) { buffer->data[0] = size; },
- [&](rpc::Buffer *buffer) {
- ptr = reinterpret_cast<void *>(buffer->data[0]);
- });
- port.close();
- return ptr;
+ return gpu::allocate(size);
}
} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/str_from_util.h b/src/stdlib/str_from_util.h
new file mode 100644
index 000000000000..58afa98afc08
--- /dev/null
+++ b/src/stdlib/str_from_util.h
@@ -0,0 +1,138 @@
+//===-- Implementation header for strfromx() utilitites -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// According to the C23 standard, any input character sequences except a
+// precision specifier and the usual floating point formats, namely
+// %{a,A,e,E,f,F,g,G}, are not allowed and any code that does otherwise results
+// in undefined behaviour(including use of a '%%' conversion specifier); which
+// in this case is that the buffer string is simply populated with the format
+// string. The case of the input being nullptr should be handled in the calling
+// function (strfromf, strfromd, strfroml) itself.
+
+#ifndef LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H
+#define LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H
+
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/str_to_integer.h"
+#include "src/stdio/printf_core/converter_atlas.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE::internal {
+
+template <typename T>
+using storage_type = typename fputil::FPBits<T>::StorageType;
+
+template <typename T>
+printf_core::FormatSection parse_format_string(const char *__restrict format,
+ T fp) {
+ printf_core::FormatSection section;
+ size_t cur_pos = 0;
+
+ // There is no typed conversion function to convert single precision float
+ // to hex exponential format, and the function convert_float_hex_exp()
+ // requires a double or long double value to work correctly.
+ // To work around this, we convert fp to double if it is single precision, and
+ // then use that double precision value in the %{A, a} conversion specifiers.
+ [[maybe_unused]] double new_fp;
+ bool t_is_single_prec_type = cpp::is_same<T, float>::value;
+ if (t_is_single_prec_type)
+ new_fp = (double)fp;
+
+ if (format[cur_pos] == '%') {
+ section.has_conv = true;
+ ++cur_pos;
+
+ // handle precision
+ section.precision = -1;
+ if (format[cur_pos] == '.') {
+ ++cur_pos;
+ section.precision = 0;
+
+ // The standard does not allow the '*' (asterisk) operator for strfromx()
+ // functions
+ if (internal::isdigit(format[cur_pos])) {
+ auto result = internal::strtointeger<int>(format + cur_pos, 10);
+ section.precision += result.value;
+ cur_pos += result.parsed_len;
+ }
+ }
+
+ section.conv_name = format[cur_pos];
+ switch (format[cur_pos]) {
+ case 'a':
+ case 'A':
+ if (t_is_single_prec_type)
+ section.conv_val_raw = cpp::bit_cast<storage_type<double>>(new_fp);
+ else
+ section.conv_val_raw = cpp::bit_cast<storage_type<T>>(fp);
+ break;
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ section.conv_val_raw = cpp::bit_cast<storage_type<T>>(fp);
+ break;
+ default:
+ section.has_conv = false;
+ while (format[cur_pos] != '\0')
+ ++cur_pos;
+ break;
+ }
+
+ if (format[cur_pos] != '\0')
+ ++cur_pos;
+ } else {
+ section.has_conv = false;
+ // We are looking for exactly one section, so no more '%'
+ while (format[cur_pos] != '\0')
+ ++cur_pos;
+ }
+
+ section.raw_string = {format, cur_pos};
+ return section;
+}
+
+template <typename T>
+int strfromfloat_convert(printf_core::Writer *writer,
+ const printf_core::FormatSection &section) {
+ if (!section.has_conv)
+ return writer->write(section.raw_string);
+
+ auto res = static_cast<storage_type<T>>(section.conv_val_raw);
+
+ fputil::FPBits<T> strfromfloat_bits(res);
+ if (strfromfloat_bits.is_inf_or_nan())
+ return convert_inf_nan(writer, section);
+
+ switch (section.conv_name) {
+ case 'f':
+ case 'F':
+ return convert_float_decimal_typed(writer, section, strfromfloat_bits);
+ case 'e':
+ case 'E':
+ return convert_float_dec_exp_typed(writer, section, strfromfloat_bits);
+ case 'a':
+ case 'A':
+ return convert_float_hex_exp(writer, section);
+ case 'g':
+ case 'G':
+ return convert_float_dec_auto_typed(writer, section, strfromfloat_bits);
+ default:
+ return writer->write(section.raw_string);
+ }
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE::internal
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H
diff --git a/src/stdlib/strfromd.cpp b/src/stdlib/strfromd.cpp
new file mode 100644
index 000000000000..329f6fdcaff7
--- /dev/null
+++ b/src/stdlib/strfromd.cpp
@@ -0,0 +1,39 @@
+//===-- Implementation of strfromd ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strfromd.h"
+#include "src/stdlib/str_from_util.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, strfromd,
+ (char *__restrict s, size_t n, const char *__restrict format,
+ double fp)) {
+ LIBC_ASSERT(s != nullptr);
+
+ printf_core::FormatSection section =
+ internal::parse_format_string(format, fp);
+ printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0));
+ printf_core::Writer writer(&wb);
+
+ int result = 0;
+ if (section.has_conv)
+ result = internal::strfromfloat_convert<double>(&writer, section);
+ else
+ result = writer.write(section.raw_string);
+
+ if (result < 0)
+ return result;
+
+ if (n > 0)
+ wb.buff[wb.buff_cur] = '\0';
+
+ return writer.get_chars_written();
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/strfromd.h b/src/stdlib/strfromd.h
new file mode 100644
index 000000000000..d2c3fefb6300
--- /dev/null
+++ b/src/stdlib/strfromd.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for strfromd ------------------------*- 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_STDLIB_STRFROMD_H
+#define LLVM_LIBC_SRC_STDLIB_STRFROMD_H
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE {
+
+int strfromd(char *__restrict s, size_t n, const char *__restrict format,
+ double fp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRFROMD_H
diff --git a/src/stdlib/strfromf.cpp b/src/stdlib/strfromf.cpp
new file mode 100644
index 000000000000..80e1d74797c8
--- /dev/null
+++ b/src/stdlib/strfromf.cpp
@@ -0,0 +1,39 @@
+//===-- Implementation of strfromf ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strfromf.h"
+#include "src/stdlib/str_from_util.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, strfromf,
+ (char *__restrict s, size_t n, const char *__restrict format,
+ float fp)) {
+ LIBC_ASSERT(s != nullptr);
+
+ printf_core::FormatSection section =
+ internal::parse_format_string(format, fp);
+ printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0));
+ printf_core::Writer writer(&wb);
+
+ int result = 0;
+ if (section.has_conv)
+ result = internal::strfromfloat_convert<float>(&writer, section);
+ else
+ result = writer.write(section.raw_string);
+
+ if (result < 0)
+ return result;
+
+ if (n > 0)
+ wb.buff[wb.buff_cur] = '\0';
+
+ return writer.get_chars_written();
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/strfromf.h b/src/stdlib/strfromf.h
new file mode 100644
index 000000000000..492c2c33cf08
--- /dev/null
+++ b/src/stdlib/strfromf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for strfromf ------------------------*- 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_STDLIB_STRFROMF_H
+#define LLVM_LIBC_SRC_STDLIB_STRFROMF_H
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE {
+
+int strfromf(char *__restrict s, size_t n, const char *__restrict format,
+ float fp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRFROMF_H
diff --git a/src/stdlib/strfroml.cpp b/src/stdlib/strfroml.cpp
new file mode 100644
index 000000000000..f0bc9354c7ad
--- /dev/null
+++ b/src/stdlib/strfroml.cpp
@@ -0,0 +1,44 @@
+//===-- Implementation of strfroml ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/strfroml.h"
+#include "src/stdlib/str_from_util.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, strfroml,
+ (char *__restrict s, size_t n, const char *__restrict format,
+ long double fp)) {
+ LIBC_ASSERT(s != nullptr);
+
+ printf_core::FormatSection section =
+ internal::parse_format_string(format, fp);
+
+ // To ensure that the conversion function actually uses long double,
+ // the length modifier has to be set to LenghtModifier::L
+ section.length_modifier = printf_core::LengthModifier::L;
+
+ printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0));
+ printf_core::Writer writer(&wb);
+
+ int result = 0;
+ if (section.has_conv)
+ result = internal::strfromfloat_convert<long double>(&writer, section);
+ else
+ result = writer.write(section.raw_string);
+
+ if (result < 0)
+ return result;
+
+ if (n > 0)
+ wb.buff[wb.buff_cur] = '\0';
+
+ return writer.get_chars_written();
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/stdlib/strfroml.h b/src/stdlib/strfroml.h
new file mode 100644
index 000000000000..e99d035e4da6
--- /dev/null
+++ b/src/stdlib/strfroml.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for strfroml ------------------------*- 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_STDLIB_STRFROML_H
+#define LLVM_LIBC_SRC_STDLIB_STRFROML_H
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE {
+
+int strfroml(char *__restrict s, size_t n, const char *__restrict format,
+ long double fp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRFROML_H
diff --git a/src/stdlib/strtod.cpp b/src/stdlib/strtod.cpp
index db5e0edefb5b..461f7feb5bf6 100644
--- a/src/stdlib/strtod.cpp
+++ b/src/stdlib/strtod.cpp
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(double, strtod,
if (result.has_error())
libc_errno = result.error;
- if (str_end != NULL)
+ if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
diff --git a/src/stdlib/strtof.cpp b/src/stdlib/strtof.cpp
index 2cc8829f63d3..554d096879c5 100644
--- a/src/stdlib/strtof.cpp
+++ b/src/stdlib/strtof.cpp
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(float, strtof,
if (result.has_error())
libc_errno = result.error;
- if (str_end != NULL)
+ if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
diff --git a/src/stdlib/strtold.cpp b/src/stdlib/strtold.cpp
index 7378963f21b2..9c3e1db90067 100644
--- a/src/stdlib/strtold.cpp
+++ b/src/stdlib/strtold.cpp
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(long double, strtold,
if (result.has_error())
libc_errno = result.error;
- if (str_end != NULL)
+ if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
diff --git a/src/string/memory_utils/aarch64/inline_bcmp.h b/src/string/memory_utils/aarch64/inline_bcmp.h
index 8e0827f1361f..b80b57818763 100644
--- a/src/string/memory_utils/aarch64/inline_bcmp.h
+++ b/src/string/memory_utils/aarch64/inline_bcmp.h
@@ -27,7 +27,7 @@ namespace LIBC_NAMESPACE {
}
switch (count) {
case 0:
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
case 1:
return generic::Bcmp<uint8_t>::block(p1, p2);
case 2:
diff --git a/src/string/memory_utils/aarch64/inline_memcmp.h b/src/string/memory_utils/aarch64/inline_memcmp.h
index 839c8ec13854..d0e0bd7cf025 100644
--- a/src/string/memory_utils/aarch64/inline_memcmp.h
+++ b/src/string/memory_utils/aarch64/inline_memcmp.h
@@ -50,7 +50,7 @@ inline_memcmp_aarch64_neon_gt16(CPtr p1, CPtr p2, size_t count) {
LIBC_INLINE MemcmpReturnType inline_memcmp_aarch64(CPtr p1, CPtr p2,
size_t count) {
if (count == 0)
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
if (count == 1)
return generic::Memcmp<uint8_t>::block(p1, p2);
if (count == 2)
diff --git a/src/string/memory_utils/aarch64/inline_memcpy.h b/src/string/memory_utils/aarch64/inline_memcpy.h
index 0a159f476cd6..ea1a03f4fa0b 100644
--- a/src/string/memory_utils/aarch64/inline_memcpy.h
+++ b/src/string/memory_utils/aarch64/inline_memcpy.h
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#ifndef LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
-#define LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
+#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
#include "src/__support/macros/config.h" // LIBC_INLINE
#include "src/string/memory_utils/op_builtin.h"
@@ -45,4 +45,4 @@ inline_memcpy_aarch64(Ptr __restrict dst, CPtr __restrict src, size_t count) {
} // namespace LIBC_NAMESPACE
-#endif // LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
diff --git a/src/string/memory_utils/generic/aligned_access.h b/src/string/memory_utils/generic/aligned_access.h
index 65bc63f6cbe5..b6ece816756c 100644
--- a/src/string/memory_utils/generic/aligned_access.h
+++ b/src/string/memory_utils/generic/aligned_access.h
@@ -135,7 +135,7 @@ inline_bcmp_aligned_access_32bit(CPtr p1, CPtr p2, size_t count) {
uint32_t a = load32_aligned<uint32_t>(p1, offset);
uint32_t b = load32_aligned(p2, offset, p2_alignment);
if (a != b)
- return BcmpReturnType::NONZERO();
+ return BcmpReturnType::nonzero();
}
return inline_bcmp_byte_per_byte(p1, p2, count, offset);
}
@@ -154,7 +154,7 @@ inline_bcmp_aligned_access_64bit(CPtr p1, CPtr p2, size_t count) {
uint64_t a = load64_aligned<uint64_t>(p1, offset);
uint64_t b = load64_aligned(p2, offset, p2_alignment);
if (a != b)
- return BcmpReturnType::NONZERO();
+ return BcmpReturnType::nonzero();
}
return inline_bcmp_byte_per_byte(p1, p2, count, offset);
}
diff --git a/src/string/memory_utils/generic/builtin.h b/src/string/memory_utils/generic/builtin.h
index 5239329f653b..ba4f4b898408 100644
--- a/src/string/memory_utils/generic/builtin.h
+++ b/src/string/memory_utils/generic/builtin.h
@@ -10,16 +10,16 @@
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BUILTIN_H
#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
#include "src/string/memory_utils/utils.h" // Ptr, CPtr
#include <stddef.h> // size_t
namespace LIBC_NAMESPACE {
-static_assert(LIBC_HAS_BUILTIN(__builtin_memcpy), "Builtin not defined");
-static_assert(LIBC_HAS_BUILTIN(__builtin_memset), "Builtin not defined");
-static_assert(LIBC_HAS_BUILTIN(__builtin_memmove), "Builtin not defined");
+#if !__has_builtin(__builtin_memcpy) || !__has_builtin(__builtin_memset) || \
+ !__has_builtin(__builtin_memmove)
+#error "Builtin not defined");
+#endif
[[maybe_unused]] LIBC_INLINE void
inline_memcpy_builtin(Ptr dst, CPtr src, size_t count, size_t offset = 0) {
diff --git a/src/string/memory_utils/generic/byte_per_byte.h b/src/string/memory_utils/generic/byte_per_byte.h
index a666c5da3136..9515398794df 100644
--- a/src/string/memory_utils/generic/byte_per_byte.h
+++ b/src/string/memory_utils/generic/byte_per_byte.h
@@ -56,8 +56,8 @@ inline_bcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) {
LIBC_LOOP_NOUNROLL
for (; offset < count; ++offset)
if (p1[offset] != p2[offset])
- return BcmpReturnType::NONZERO();
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::nonzero();
+ return BcmpReturnType::zero();
}
[[maybe_unused]] LIBC_INLINE MemcmpReturnType
@@ -70,7 +70,7 @@ inline_memcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) {
if (diff)
return diff;
}
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
} // namespace LIBC_NAMESPACE
diff --git a/src/string/memory_utils/op_aarch64.h b/src/string/memory_utils/op_aarch64.h
index 3aae328945dd..6a2013b2a8fa 100644
--- a/src/string/memory_utils/op_aarch64.h
+++ b/src/string/memory_utils/op_aarch64.h
@@ -108,7 +108,7 @@ template <size_t Size> struct Bcmp {
} else {
static_assert(cpp::always_false<decltype(Size)>, "SIZE not implemented");
}
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
LIBC_INLINE static BcmpReturnType tail(CPtr p1, CPtr p2, size_t count) {
@@ -154,7 +154,7 @@ template <size_t Size> struct Bcmp {
} else {
static_assert(cpp::always_false<decltype(Size)>, "SIZE not implemented");
}
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
LIBC_INLINE static BcmpReturnType loop_and_tail(CPtr p1, CPtr p2,
@@ -217,7 +217,7 @@ LIBC_INLINE MemcmpReturnType cmp<uint64_t>(CPtr p1, CPtr p2, size_t offset) {
const auto b = load_be<uint64_t>(p2, offset);
if (a != b)
return a > b ? 1 : -1;
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
///////////////////////////////////////////////////////////////////////////////
@@ -245,7 +245,7 @@ LIBC_INLINE MemcmpReturnType cmp<uint8x16_t>(CPtr p1, CPtr p2, size_t offset) {
return cmp_neq_uint64_t(a, b);
offset += sizeof(uint64_t);
}
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
///////////////////////////////////////////////////////////////////////////////
@@ -262,7 +262,7 @@ LIBC_INLINE MemcmpReturnType cmp<uint8x16x2_t>(CPtr p1, CPtr p2,
return cmp_neq_uint64_t(a, b);
offset += sizeof(uint64_t);
}
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
} // namespace LIBC_NAMESPACE::generic
diff --git a/src/string/memory_utils/op_builtin.h b/src/string/memory_utils/op_builtin.h
index 3c17eef781e5..75dd4de53a47 100644
--- a/src/string/memory_utils/op_builtin.h
+++ b/src/string/memory_utils/op_builtin.h
@@ -105,22 +105,22 @@ template <size_t Size> struct Bcmp {
LIBC_INLINE static BcmpReturnType block(CPtr, CPtr) {
static_assert(cpp::always_false<decltype(Size)>,
"Missing __builtin_memcmp_inline");
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
LIBC_INLINE static BcmpReturnType tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
LIBC_INLINE static BcmpReturnType head_tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
LIBC_INLINE static BcmpReturnType loop_and_tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
};
@@ -132,22 +132,22 @@ template <size_t Size> struct Memcmp {
LIBC_INLINE static MemcmpReturnType block(CPtr, CPtr) {
static_assert(cpp::always_false<decltype(Size)>,
"Missing __builtin_memcmp_inline");
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
LIBC_INLINE static MemcmpReturnType tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
LIBC_INLINE static MemcmpReturnType head_tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
LIBC_INLINE static MemcmpReturnType loop_and_tail(CPtr, CPtr, size_t) {
static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
};
diff --git a/src/string/memory_utils/op_generic.h b/src/string/memory_utils/op_generic.h
index db218f8577ab..efaff80b7e4d 100644
--- a/src/string/memory_utils/op_generic.h
+++ b/src/string/memory_utils/op_generic.h
@@ -28,6 +28,7 @@
#include "src/__support/common.h"
#include "src/__support/endian.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT64
#include "src/string/memory_utils/op_builtin.h"
#include "src/string/memory_utils/utils.h"
@@ -37,10 +38,6 @@ static_assert((UINTPTR_MAX == 4294967295U) ||
(UINTPTR_MAX == 18446744073709551615UL),
"We currently only support 32- or 64-bit platforms");
-#if defined(UINT64_MAX)
-#define LLVM_LIBC_HAS_UINT64
-#endif
-
namespace LIBC_NAMESPACE {
// Compiler types using the vector attributes.
using generic_v128 = uint8_t __attribute__((__vector_size__(16)));
@@ -60,31 +57,44 @@ template <typename T> struct is_scalar : cpp::false_type {};
template <> struct is_scalar<uint8_t> : cpp::true_type {};
template <> struct is_scalar<uint16_t> : cpp::true_type {};
template <> struct is_scalar<uint32_t> : cpp::true_type {};
-#ifdef LLVM_LIBC_HAS_UINT64
+#ifdef LIBC_TYPES_HAS_INT64
template <> struct is_scalar<uint64_t> : cpp::true_type {};
-#endif // LLVM_LIBC_HAS_UINT64
+#endif // LIBC_TYPES_HAS_INT64
+// Meant to match std::numeric_limits interface.
+// NOLINTNEXTLINE(readability-identifier-naming)
template <typename T> constexpr bool is_scalar_v = is_scalar<T>::value;
template <typename T> struct is_vector : cpp::false_type {};
template <> struct is_vector<generic_v128> : cpp::true_type {};
template <> struct is_vector<generic_v256> : cpp::true_type {};
template <> struct is_vector<generic_v512> : cpp::true_type {};
+// Meant to match std::numeric_limits interface.
+// NOLINTNEXTLINE(readability-identifier-naming)
template <typename T> constexpr bool is_vector_v = is_vector<T>::value;
template <class T> struct is_array : cpp::false_type {};
template <class T, size_t N> struct is_array<cpp::array<T, N>> {
+ // Meant to match std::numeric_limits interface.
+ // NOLINTNEXTLINE(readability-identifier-naming)
static constexpr bool value = is_scalar_v<T> || is_vector_v<T>;
};
+// Meant to match std::numeric_limits interface.
+// NOLINTNEXTLINE(readability-identifier-naming)
template <typename T> constexpr bool is_array_v = is_array<T>::value;
+// Meant to match std::numeric_limits interface.
+// NOLINTBEGIN(readability-identifier-naming)
template <typename T>
constexpr bool is_element_type_v =
is_scalar_v<T> || is_vector_v<T> || is_array_v<T>;
+// NOLINTEND(readability-identifier-naming)
// Helper struct to retrieve the number of elements of an array.
template <class T> struct array_size {};
template <class T, size_t N>
struct array_size<cpp::array<T, N>> : cpp::integral_constant<size_t, N> {};
+// Meant to match std::numeric_limits interface.
+// NOLINTNEXTLINE(readability-identifier-naming)
template <typename T> constexpr size_t array_size_v = array_size<T>::value;
// Generic operations for the above type categories.
@@ -95,10 +105,10 @@ template <typename T> T load(CPtr src) {
return ::LIBC_NAMESPACE::load<T>(src);
} else if constexpr (is_array_v<T>) {
using value_type = typename T::value_type;
- T Value;
- for (size_t I = 0; I < array_size_v<T>; ++I)
- Value[I] = load<value_type>(src + (I * sizeof(value_type)));
- return Value;
+ T value;
+ for (size_t i = 0; i < array_size_v<T>; ++i)
+ value[i] = load<value_type>(src + (i * sizeof(value_type)));
+ return value;
}
}
@@ -108,8 +118,8 @@ template <typename T> void store(Ptr dst, T value) {
::LIBC_NAMESPACE::store<T>(dst, value);
} else if constexpr (is_array_v<T>) {
using value_type = typename T::value_type;
- for (size_t I = 0; I < array_size_v<T>; ++I)
- store<value_type>(dst + (I * sizeof(value_type)), value[I]);
+ for (size_t i = 0; i < array_size_v<T>; ++i)
+ store<value_type>(dst + (i * sizeof(value_type)), value[i]);
}
}
@@ -118,11 +128,11 @@ template <typename T> T splat(uint8_t value) {
if constexpr (is_scalar_v<T>)
return T(~0) / T(0xFF) * T(value);
else if constexpr (is_vector_v<T>) {
- T Out;
+ T out;
// This for loop is optimized out for vector types.
for (size_t i = 0; i < sizeof(T); ++i)
- Out[i] = value;
- return Out;
+ out[i] = value;
+ return out;
}
}
@@ -140,8 +150,8 @@ template <typename T> struct Memset {
} else if constexpr (is_array_v<T>) {
using value_type = typename T::value_type;
const auto Splat = splat<value_type>(value);
- for (size_t I = 0; I < array_size_v<T>; ++I)
- store<value_type>(dst + (I * sizeof(value_type)), Splat);
+ for (size_t i = 0; i < array_size_v<T>; ++i)
+ store<value_type>(dst + (i * sizeof(value_type)), Splat);
}
}
@@ -390,7 +400,7 @@ private:
if constexpr (cmp_is_expensive<T>::value) {
if (!eq<T>(p1, p2, offset))
return cmp_neq<T>(p1, p2, offset);
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
} else {
return cmp<T>(p1, p2, offset);
}
@@ -443,7 +453,7 @@ public:
for (; offset < count; offset += SIZE)
if (auto value = cmp<T>(p1, p2, offset))
return value;
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
}
@@ -453,7 +463,7 @@ public:
if (LIBC_UNLIKELY(count >= threshold) && helper.not_aligned()) {
if (auto value = block(p1, p2))
return value;
- adjust(helper.offset(), p1, p2, count);
+ adjust(helper.offset, p1, p2, count);
}
return loop_and_tail(p1, p2, count);
}
@@ -475,7 +485,7 @@ template <typename T, typename... TS> struct MemcmpSequence {
if constexpr (sizeof...(TS) > 0)
return MemcmpSequence<TS...>::block(p1 + sizeof(T), p2 + sizeof(T));
else
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
}
};
@@ -521,7 +531,7 @@ template <typename T> struct Bcmp {
for (; offset < count; offset += SIZE)
if (const auto value = neq<T>(p1, p2, offset))
return value;
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
}
@@ -533,7 +543,7 @@ template <typename T> struct Bcmp {
if (LIBC_UNLIKELY(count >= threshold) && helper.not_aligned()) {
if (auto value = block(p1, p2))
return value;
- adjust(helper.offset(), p1, p2, count);
+ adjust(helper.offset, p1, p2, count);
}
return loop_and_tail(p1, p2, count);
}
@@ -547,7 +557,7 @@ template <typename T, typename... TS> struct BcmpSequence {
if constexpr (sizeof...(TS) > 0)
return BcmpSequence<TS...>::block(p1 + sizeof(T), p2 + sizeof(T));
else
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
}
};
diff --git a/src/string/memory_utils/op_x86.h b/src/string/memory_utils/op_x86.h
index 2852636c48a7..1afa91f20e65 100644
--- a/src/string/memory_utils/op_x86.h
+++ b/src/string/memory_utils/op_x86.h
@@ -40,12 +40,12 @@
namespace LIBC_NAMESPACE::x86 {
// A set of constants to check compile time features.
-LIBC_INLINE_VAR constexpr bool kSse2 = LLVM_LIBC_IS_DEFINED(__SSE2__);
-LIBC_INLINE_VAR constexpr bool kSse41 = LLVM_LIBC_IS_DEFINED(__SSE4_1__);
-LIBC_INLINE_VAR constexpr bool kAvx = LLVM_LIBC_IS_DEFINED(__AVX__);
-LIBC_INLINE_VAR constexpr bool kAvx2 = LLVM_LIBC_IS_DEFINED(__AVX2__);
-LIBC_INLINE_VAR constexpr bool kAvx512F = LLVM_LIBC_IS_DEFINED(__AVX512F__);
-LIBC_INLINE_VAR constexpr bool kAvx512BW = LLVM_LIBC_IS_DEFINED(__AVX512BW__);
+LIBC_INLINE_VAR constexpr bool K_SSE2 = LLVM_LIBC_IS_DEFINED(__SSE2__);
+LIBC_INLINE_VAR constexpr bool K_SSE41 = LLVM_LIBC_IS_DEFINED(__SSE4_1__);
+LIBC_INLINE_VAR constexpr bool K_AVX = LLVM_LIBC_IS_DEFINED(__AVX__);
+LIBC_INLINE_VAR constexpr bool K_AVX2 = LLVM_LIBC_IS_DEFINED(__AVX2__);
+LIBC_INLINE_VAR constexpr bool K_AVX512_F = LLVM_LIBC_IS_DEFINED(__AVX512F__);
+LIBC_INLINE_VAR constexpr bool K_AVX512_BW = LLVM_LIBC_IS_DEFINED(__AVX512BW__);
///////////////////////////////////////////////////////////////////////////////
// Memcpy repmovsb implementation
diff --git a/src/string/memory_utils/riscv/inline_memmove.h b/src/string/memory_utils/riscv/inline_memmove.h
index 1c26917a96d9..1a95a8ebba07 100644
--- a/src/string/memory_utils/riscv/inline_memmove.h
+++ b/src/string/memory_utils/riscv/inline_memmove.h
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#ifndef LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
-#define LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
+#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/properties/architectures.h" // LIBC_TARGET_ARCH_IS_RISCV64
@@ -24,4 +24,4 @@ inline_memmove_riscv(Ptr __restrict dst, CPtr __restrict src, size_t count) {
} // namespace LIBC_NAMESPACE
-#endif // LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMMOVE_H
diff --git a/src/string/memory_utils/utils.h b/src/string/memory_utils/utils.h
index 543d45b7c4e3..b3e1a26ad996 100644
--- a/src/string/memory_utils/utils.h
+++ b/src/string/memory_utils/utils.h
@@ -14,7 +14,6 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/endian.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
-#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
#include "src/__support/macros/properties/architectures.h"
#include <stddef.h> // size_t
@@ -71,11 +70,11 @@ LIBC_INLINE bool is_disjoint(const void *p1, const void *p2, size_t size) {
return sdiff >= 0 ? size <= udiff : size <= neg_udiff;
}
-#if LIBC_HAS_BUILTIN(__builtin_memcpy_inline)
+#if __has_builtin(__builtin_memcpy_inline)
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
#endif
-#if LIBC_HAS_BUILTIN(__builtin_memset_inline)
+#if __has_builtin(__builtin_memset_inline)
#define LLVM_LIBC_HAS_BUILTIN_MEMSET_INLINE
#endif
@@ -130,8 +129,8 @@ template <typename T> struct StrictIntegralType {
}
// Helper to get the zero value.
- LIBC_INLINE static constexpr StrictIntegralType ZERO() { return {T(0)}; }
- LIBC_INLINE static constexpr StrictIntegralType NONZERO() { return {T(1)}; }
+ LIBC_INLINE static constexpr StrictIntegralType zero() { return {T(0)}; }
+ LIBC_INLINE static constexpr StrictIntegralType nonzero() { return {T(1)}; }
private:
T value;
@@ -205,9 +204,9 @@ LIBC_INLINE MemcmpReturnType cmp_neq_uint64_t(uint64_t a, uint64_t b) {
// Loads bytes from memory (possibly unaligned) and materializes them as
// type.
template <typename T> LIBC_INLINE T load(CPtr ptr) {
- T Out;
- memcpy_inline<sizeof(T)>(&Out, ptr);
- return Out;
+ T out;
+ memcpy_inline<sizeof(T)>(&out, ptr);
+ return out;
}
// Stores a value of type T in memory (possibly unaligned).
@@ -228,12 +227,12 @@ LIBC_INLINE ValueType load_aligned(CPtr src) {
static_assert(sizeof(ValueType) >= (sizeof(T) + ... + sizeof(TS)));
const ValueType value = load<T>(assume_aligned<sizeof(T)>(src));
if constexpr (sizeof...(TS) > 0) {
- constexpr size_t shift = sizeof(T) * 8;
+ constexpr size_t SHIFT = sizeof(T) * 8;
const ValueType next = load_aligned<ValueType, TS...>(src + sizeof(T));
if constexpr (Endian::IS_LITTLE)
- return value | (next << shift);
+ return value | (next << SHIFT);
else if constexpr (Endian::IS_BIG)
- return (value << shift) | next;
+ return (value << SHIFT) | next;
else
static_assert(cpp::always_false<T>, "Invalid endianness");
} else {
@@ -261,16 +260,16 @@ LIBC_INLINE auto load64_aligned(CPtr src, size_t offset) {
template <typename ValueType, typename T, typename... TS>
LIBC_INLINE void store_aligned(ValueType value, Ptr dst) {
static_assert(sizeof(ValueType) >= (sizeof(T) + ... + sizeof(TS)));
- constexpr size_t shift = sizeof(T) * 8;
+ constexpr size_t SHIFT = sizeof(T) * 8;
if constexpr (Endian::IS_LITTLE) {
store<T>(assume_aligned<sizeof(T)>(dst), value & ~T(0));
if constexpr (sizeof...(TS) > 0)
- store_aligned<ValueType, TS...>(value >> shift, dst + sizeof(T));
+ store_aligned<ValueType, TS...>(value >> SHIFT, dst + sizeof(T));
} else if constexpr (Endian::IS_BIG) {
constexpr size_t OFFSET = (0 + ... + sizeof(TS));
store<T>(assume_aligned<sizeof(T)>(dst + OFFSET), value & ~T(0));
if constexpr (sizeof...(TS) > 0)
- store_aligned<ValueType, TS...>(value >> shift, dst);
+ store_aligned<ValueType, TS...>(value >> SHIFT, dst);
} else {
static_assert(cpp::always_false<T>, "Invalid endianness");
}
@@ -336,13 +335,10 @@ LIBC_INLINE void align_to_next_boundary(T1 *__restrict &p1, T2 *__restrict &p2,
template <size_t SIZE> struct AlignHelper {
LIBC_INLINE AlignHelper(CPtr ptr)
- : offset_(distance_to_next_aligned<SIZE>(ptr)) {}
+ : offset(distance_to_next_aligned<SIZE>(ptr)) {}
- LIBC_INLINE bool not_aligned() const { return offset_ != SIZE; }
- LIBC_INLINE uintptr_t offset() const { return offset_; }
-
-private:
- uintptr_t offset_;
+ LIBC_INLINE bool not_aligned() const { return offset != SIZE; }
+ uintptr_t offset;
};
LIBC_INLINE void prefetch_for_write(CPtr dst) {
diff --git a/src/string/memory_utils/x86_64/inline_bcmp.h b/src/string/memory_utils/x86_64/inline_bcmp.h
index 31aff86e6059..58eaedbbe015 100644
--- a/src/string/memory_utils/x86_64/inline_bcmp.h
+++ b/src/string/memory_utils/x86_64/inline_bcmp.h
@@ -58,7 +58,7 @@ inline_bcmp_x86_avx512bw_gt16(CPtr p1, CPtr p2, size_t count) {
[[maybe_unused]] LIBC_INLINE BcmpReturnType inline_bcmp_x86(CPtr p1, CPtr p2,
size_t count) {
if (count == 0)
- return BcmpReturnType::ZERO();
+ return BcmpReturnType::zero();
if (count == 1)
return generic::Bcmp<uint8_t>::block(p1, p2);
if (count == 2)
diff --git a/src/string/memory_utils/x86_64/inline_memcmp.h b/src/string/memory_utils/x86_64/inline_memcmp.h
index d5fa77cdbbcd..6a315adcd566 100644
--- a/src/string/memory_utils/x86_64/inline_memcmp.h
+++ b/src/string/memory_utils/x86_64/inline_memcmp.h
@@ -59,7 +59,7 @@ inline_memcmp_x86_avx512bw_gt16(CPtr p1, CPtr p2, size_t count) {
LIBC_INLINE MemcmpReturnType inline_memcmp_x86(CPtr p1, CPtr p2, size_t count) {
if (count == 0)
- return MemcmpReturnType::ZERO();
+ return MemcmpReturnType::zero();
if (count == 1)
return generic::Memcmp<uint8_t>::block(p1, p2);
if (count == 2)
diff --git a/src/string/memory_utils/x86_64/inline_memcpy.h b/src/string/memory_utils/x86_64/inline_memcpy.h
index dd09d4f3e812..ae61b1235bd0 100644
--- a/src/string/memory_utils/x86_64/inline_memcpy.h
+++ b/src/string/memory_utils/x86_64/inline_memcpy.h
@@ -30,11 +30,11 @@ namespace LIBC_NAMESPACE {
namespace x86 {
-LIBC_INLINE_VAR constexpr size_t kOneCacheline = 64;
-LIBC_INLINE_VAR constexpr size_t kTwoCachelines = 2 * kOneCacheline;
-LIBC_INLINE_VAR constexpr size_t kThreeCachelines = 3 * kOneCacheline;
+LIBC_INLINE_VAR constexpr size_t K_ONE_CACHELINE = 64;
+LIBC_INLINE_VAR constexpr size_t K_TWO_CACHELINES = 2 * K_ONE_CACHELINE;
+LIBC_INLINE_VAR constexpr size_t K_THREE_CACHELINES = 3 * K_ONE_CACHELINE;
-LIBC_INLINE_VAR constexpr bool kUseSoftwarePrefetching =
+LIBC_INLINE_VAR constexpr bool K_USE_SOFTWARE_PREFETCHING =
LLVM_LIBC_IS_DEFINED(LIBC_COPT_MEMCPY_X86_USE_SOFTWARE_PREFETCHING);
// Whether to use rep;movsb exclusively (0), not at all (SIZE_MAX), or only
@@ -42,7 +42,7 @@ LIBC_INLINE_VAR constexpr bool kUseSoftwarePrefetching =
#ifndef LIBC_COPT_MEMCPY_X86_USE_REPMOVSB_FROM_SIZE
#define LIBC_COPT_MEMCPY_X86_USE_REPMOVSB_FROM_SIZE SIZE_MAX
#endif
-LIBC_INLINE_VAR constexpr size_t kRepMovsbThreshold =
+LIBC_INLINE_VAR constexpr size_t K_REP_MOVSB_THRESHOLD =
LIBC_COPT_MEMCPY_X86_USE_REPMOVSB_FROM_SIZE;
} // namespace x86
@@ -73,10 +73,10 @@ inline_memcpy_x86_avx_ge64(Ptr __restrict dst, CPtr __restrict src,
inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
CPtr __restrict src, size_t count) {
using namespace LIBC_NAMESPACE::x86;
- prefetch_to_local_cache(src + kOneCacheline);
+ prefetch_to_local_cache(src + K_ONE_CACHELINE);
if (count <= 128)
return builtin::Memcpy<64>::head_tail(dst, src, count);
- prefetch_to_local_cache(src + kTwoCachelines);
+ prefetch_to_local_cache(src + K_TWO_CACHELINES);
// Aligning 'dst' on a 32B boundary.
builtin::Memcpy<32>::block(dst, src);
align_to_next_boundary<32, Arg::Dst>(dst, src, count);
@@ -89,22 +89,22 @@ inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
// - count >= 128.
if (count < 352) {
// Two cache lines at a time.
- while (offset + kTwoCachelines + 32 <= count) {
- prefetch_to_local_cache(src + offset + kOneCacheline);
- prefetch_to_local_cache(src + offset + kTwoCachelines);
- builtin::Memcpy<kTwoCachelines>::block_offset(dst, src, offset);
- offset += kTwoCachelines;
+ while (offset + K_TWO_CACHELINES + 32 <= count) {
+ prefetch_to_local_cache(src + offset + K_ONE_CACHELINE);
+ prefetch_to_local_cache(src + offset + K_TWO_CACHELINES);
+ builtin::Memcpy<K_TWO_CACHELINES>::block_offset(dst, src, offset);
+ offset += K_TWO_CACHELINES;
}
} else {
// Three cache lines at a time.
- while (offset + kThreeCachelines + 32 <= count) {
- prefetch_to_local_cache(src + offset + kOneCacheline);
- prefetch_to_local_cache(src + offset + kTwoCachelines);
- prefetch_to_local_cache(src + offset + kThreeCachelines);
+ while (offset + K_THREE_CACHELINES + 32 <= count) {
+ prefetch_to_local_cache(src + offset + K_ONE_CACHELINE);
+ prefetch_to_local_cache(src + offset + K_TWO_CACHELINES);
+ prefetch_to_local_cache(src + offset + K_THREE_CACHELINES);
// It is likely that this copy will be turned into a 'rep;movsb' on
// non-AVX machines.
- builtin::Memcpy<kThreeCachelines>::block_offset(dst, src, offset);
- offset += kThreeCachelines;
+ builtin::Memcpy<K_THREE_CACHELINES>::block_offset(dst, src, offset);
+ offset += K_THREE_CACHELINES;
}
}
return builtin::Memcpy<32>::loop_and_tail_offset(dst, src, count, offset);
@@ -114,11 +114,11 @@ inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
CPtr __restrict src, size_t count) {
using namespace LIBC_NAMESPACE::x86;
- prefetch_to_local_cache(src + kOneCacheline);
+ prefetch_to_local_cache(src + K_ONE_CACHELINE);
if (count <= 128)
return builtin::Memcpy<64>::head_tail(dst, src, count);
- prefetch_to_local_cache(src + kTwoCachelines);
- prefetch_to_local_cache(src + kThreeCachelines);
+ prefetch_to_local_cache(src + K_TWO_CACHELINES);
+ prefetch_to_local_cache(src + K_THREE_CACHELINES);
if (count < 256)
return builtin::Memcpy<128>::head_tail(dst, src, count);
// Aligning 'dst' on a 32B boundary.
@@ -131,13 +131,13 @@ inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
// - we prefetched cachelines at 'src + 64', 'src + 128', and 'src + 196'
// - 'dst' is 32B aligned,
// - count >= 128.
- while (offset + kThreeCachelines + 64 <= count) {
+ while (offset + K_THREE_CACHELINES + 64 <= count) {
// Three cache lines at a time.
- prefetch_to_local_cache(src + offset + kOneCacheline);
- prefetch_to_local_cache(src + offset + kTwoCachelines);
- prefetch_to_local_cache(src + offset + kThreeCachelines);
- builtin::Memcpy<kThreeCachelines>::block_offset(dst, src, offset);
- offset += kThreeCachelines;
+ prefetch_to_local_cache(src + offset + K_ONE_CACHELINE);
+ prefetch_to_local_cache(src + offset + K_TWO_CACHELINES);
+ prefetch_to_local_cache(src + offset + K_THREE_CACHELINES);
+ builtin::Memcpy<K_THREE_CACHELINES>::block_offset(dst, src, offset);
+ offset += K_THREE_CACHELINES;
}
return builtin::Memcpy<64>::loop_and_tail_offset(dst, src, count, offset);
}
@@ -145,13 +145,13 @@ inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
[[maybe_unused]] LIBC_INLINE void
inline_memcpy_x86(Ptr __restrict dst, CPtr __restrict src, size_t count) {
#if defined(__AVX512F__)
- constexpr size_t vector_size = 64;
+ constexpr size_t VECTOR_SIZE = 64;
#elif defined(__AVX__)
- constexpr size_t vector_size = 32;
+ constexpr size_t VECTOR_SIZE = 32;
#elif defined(__SSE2__)
- constexpr size_t vector_size = 16;
+ constexpr size_t VECTOR_SIZE = 16;
#else
- constexpr size_t vector_size = 8;
+ constexpr size_t VECTOR_SIZE = 8;
#endif
if (count == 0)
return;
@@ -174,20 +174,20 @@ inline_memcpy_x86(Ptr __restrict dst, CPtr __restrict src, size_t count) {
// But it's not profitable to use larger size if it's not natively
// supported: we will both use more instructions and handle fewer
// sizes in earlier branches.
- if (vector_size >= 16 ? count < 16 : count <= 16)
+ if (VECTOR_SIZE >= 16 ? count < 16 : count <= 16)
return builtin::Memcpy<8>::head_tail(dst, src, count);
- if (vector_size >= 32 ? count < 32 : count <= 32)
+ if (VECTOR_SIZE >= 32 ? count < 32 : count <= 32)
return builtin::Memcpy<16>::head_tail(dst, src, count);
- if (vector_size >= 64 ? count < 64 : count <= 64)
+ if (VECTOR_SIZE >= 64 ? count < 64 : count <= 64)
return builtin::Memcpy<32>::head_tail(dst, src, count);
- if constexpr (x86::kAvx) {
- if constexpr (x86::kUseSoftwarePrefetching) {
+ if constexpr (x86::K_AVX) {
+ if constexpr (x86::K_USE_SOFTWARE_PREFETCHING) {
return inline_memcpy_x86_avx_ge64_sw_prefetching(dst, src, count);
} else {
return inline_memcpy_x86_avx_ge64(dst, src, count);
}
} else {
- if constexpr (x86::kUseSoftwarePrefetching) {
+ if constexpr (x86::K_USE_SOFTWARE_PREFETCHING) {
return inline_memcpy_x86_sse2_ge64_sw_prefetching(dst, src, count);
} else {
return inline_memcpy_x86_sse2_ge64(dst, src, count);
@@ -198,12 +198,12 @@ inline_memcpy_x86(Ptr __restrict dst, CPtr __restrict src, size_t count) {
[[maybe_unused]] LIBC_INLINE void
inline_memcpy_x86_maybe_interpose_repmovsb(Ptr __restrict dst,
CPtr __restrict src, size_t count) {
- if constexpr (x86::kRepMovsbThreshold == 0) {
+ if constexpr (x86::K_REP_MOVSB_THRESHOLD == 0) {
return x86::Memcpy::repmovsb(dst, src, count);
- } else if constexpr (x86::kRepMovsbThreshold == SIZE_MAX) {
+ } else if constexpr (x86::K_REP_MOVSB_THRESHOLD == SIZE_MAX) {
return inline_memcpy_x86(dst, src, count);
} else {
- if (LIBC_UNLIKELY(count >= x86::kRepMovsbThreshold))
+ if (LIBC_UNLIKELY(count >= x86::K_REP_MOVSB_THRESHOLD))
return x86::Memcpy::repmovsb(dst, src, count);
else
return inline_memcpy_x86(dst, src, count);
diff --git a/src/string/memory_utils/x86_64/inline_memset.h b/src/string/memory_utils/x86_64/inline_memset.h
index 41eadf2dcc00..584efcbea4be 100644
--- a/src/string/memory_utils/x86_64/inline_memset.h
+++ b/src/string/memory_utils/x86_64/inline_memset.h
@@ -18,11 +18,13 @@
namespace LIBC_NAMESPACE {
namespace x86 {
// Size of one cache line for software prefetching
-LIBC_INLINE_VAR constexpr size_t kOneCachelineSize = 64;
-LIBC_INLINE_VAR constexpr size_t kTwoCachelinesSize = kOneCachelineSize * 2;
-LIBC_INLINE_VAR constexpr size_t kFiveCachelinesSize = kOneCachelineSize * 5;
+LIBC_INLINE_VAR constexpr size_t K_ONE_CACHELINE_SIZE = 64;
+LIBC_INLINE_VAR constexpr size_t K_TWO_CACHELINES_SIZE =
+ K_ONE_CACHELINE_SIZE * 2;
+LIBC_INLINE_VAR constexpr size_t K_FIVE_CACHELINES_SIZE =
+ K_ONE_CACHELINE_SIZE * 5;
-LIBC_INLINE_VAR constexpr bool kUseSoftwarePrefetchingMemset =
+LIBC_INLINE_VAR constexpr bool K_USE_SOFTWARE_PREFETCHING_MEMSET =
LLVM_LIBC_IS_DEFINED(LIBC_COPT_MEMSET_X86_USE_SOFTWARE_PREFETCHING);
} // namespace x86
@@ -47,15 +49,15 @@ using uint512_t = cpp::array<uint64_t, 8>;
[[maybe_unused]] LIBC_INLINE static void
inline_memset_x86_gt64_sw_prefetching(Ptr dst, uint8_t value, size_t count) {
- constexpr size_t PREFETCH_DISTANCE = x86::kFiveCachelinesSize;
- constexpr size_t PREFETCH_DEGREE = x86::kTwoCachelinesSize;
+ constexpr size_t PREFETCH_DISTANCE = x86::K_FIVE_CACHELINES_SIZE;
+ constexpr size_t PREFETCH_DEGREE = x86::K_TWO_CACHELINES_SIZE;
constexpr size_t SIZE = sizeof(uint256_t);
// Prefetch one cache line
- prefetch_for_write(dst + x86::kOneCachelineSize);
+ prefetch_for_write(dst + x86::K_ONE_CACHELINE_SIZE);
if (count <= 128)
return generic::Memset<uint512_t>::head_tail(dst, value, count);
// Prefetch the second cache line
- prefetch_for_write(dst + x86::kTwoCachelinesSize);
+ prefetch_for_write(dst + x86::K_TWO_CACHELINES_SIZE);
// Aligned loop
generic::Memset<uint256_t>::block(dst, value);
align_to_next_boundary<32>(dst, count);
@@ -67,7 +69,7 @@ inline_memset_x86_gt64_sw_prefetching(Ptr dst, uint8_t value, size_t count) {
while (offset + PREFETCH_DEGREE + SIZE <= count) {
prefetch_for_write(dst + offset + PREFETCH_DISTANCE);
prefetch_for_write(dst + offset + PREFETCH_DISTANCE +
- x86::kOneCachelineSize);
+ x86::K_ONE_CACHELINE_SIZE);
for (size_t i = 0; i < PREFETCH_DEGREE; i += SIZE, offset += SIZE)
generic::Memset<uint256_t>::block(dst + offset, value);
}
@@ -93,7 +95,7 @@ inline_memset_x86(Ptr dst, uint8_t value, size_t count) {
return generic::Memset<uint128_t>::head_tail(dst, value, count);
if (count <= 64)
return generic::Memset<uint256_t>::head_tail(dst, value, count);
- if constexpr (x86::kUseSoftwarePrefetchingMemset)
+ if constexpr (x86::K_USE_SOFTWARE_PREFETCHING_MEMSET)
return inline_memset_x86_gt64_sw_prefetching(dst, value, count);
if (count <= 128)
return generic::Memset<uint512_t>::head_tail(dst, value, count);
diff --git a/src/string/memset_explicit.cpp b/src/string/memset_explicit.cpp
new file mode 100644
index 000000000000..a8656d1e791e
--- /dev/null
+++ b/src/string/memset_explicit.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of memset_explicit ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/string/memset_explicit.h"
+#include "src/__support/common.h"
+#include "src/string/memory_utils/inline_memset.h"
+
+namespace LIBC_NAMESPACE {
+
+[[gnu::noinline]] LLVM_LIBC_FUNCTION(void *, memset_explicit,
+ (void *dst, int value, size_t count)) {
+ // Use the inline memset function to set the memory.
+ inline_memset(dst, static_cast<uint8_t>(value), count);
+ // avoid dead store elimination
+ // The asm itself should also be sufficient to behave as a compiler barrier.
+ asm("" : : "r"(dst) : "memory");
+ return dst;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/string/memset_explicit.h b/src/string/memset_explicit.h
new file mode 100644
index 000000000000..f6c189761a12
--- /dev/null
+++ b/src/string/memset_explicit.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for memset_explicit ---------------*- 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_STRING_MEMSET_EXPLICIT_H
+#define LLVM_LIBC_SRC_STRING_MEMSET_EXPLICIT_H
+
+#include <stddef.h> // size_t
+
+namespace LIBC_NAMESPACE {
+
+[[gnu::noinline]] void *memset_explicit(void *ptr, int value, size_t count);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STRING_MEMSET_EXPLICIT_H
diff --git a/src/sys/epoll/epoll_pwait.h b/src/sys/epoll/epoll_pwait.h
new file mode 100644
index 000000000000..9dcb55533009
--- /dev/null
+++ b/src/sys/epoll/epoll_pwait.h
@@ -0,0 +1,26 @@
+//===-- Implementation header for epoll_pwait function ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT_H
+#define LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT_H
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/sigset_t.h"
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+// TODO: sigmask should be nullable
+int epoll_pwait(int epfd, epoll_event *events, int maxevents, int timeout,
+ const sigset_t *sigmask);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT_H
diff --git a/src/sys/epoll/epoll_pwait2.h b/src/sys/epoll/epoll_pwait2.h
new file mode 100644
index 000000000000..622ede6a0f9f
--- /dev/null
+++ b/src/sys/epoll/epoll_pwait2.h
@@ -0,0 +1,27 @@
+//===-- Implementation header for epoll_pwait2 function ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT2_H
+#define LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT2_H
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/sigset_t.h"
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+// #include "include/llvm-libc-types/struct_timespec.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+// TODO: sigmask and timeout should be nullable
+int epoll_pwait2(int epfd, epoll_event *events, int maxevents,
+ const timespec *timeout, const sigset_t *sigmask);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT2_H
diff --git a/src/sys/epoll/epoll_wait.h b/src/sys/epoll/epoll_wait.h
new file mode 100644
index 000000000000..d51c9100846c
--- /dev/null
+++ b/src/sys/epoll/epoll_wait.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for epoll_wait function -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_WAIT_H
+#define LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_WAIT_H
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+int epoll_wait(int epfd, epoll_event *events, int maxevents, int timeout);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_WAIT_H
diff --git a/src/sys/epoll/linux/epoll_pwait.cpp b/src/sys/epoll/linux/epoll_pwait.cpp
new file mode 100644
index 000000000000..ee1b4e66e984
--- /dev/null
+++ b/src/sys/epoll/linux/epoll_pwait.cpp
@@ -0,0 +1,42 @@
+//===---------- Linux implementation of the epoll_pwait 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/sys/epoll/epoll_pwait.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/sigset_t.h"
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, epoll_pwait,
+ (int epfd, struct epoll_event *events, int maxevents,
+ int timeout, const sigset_t *sigmask)) {
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(
+ SYS_epoll_pwait, epfd, reinterpret_cast<long>(events), maxevents, timeout,
+ reinterpret_cast<long>(sigmask), sizeof(sigset_t));
+
+ // A negative return value indicates an error with the magnitude of the
+ // value being the error code.
+ if (ret < 0) {
+ libc_errno = -ret;
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/epoll/linux/epoll_pwait2.cpp b/src/sys/epoll/linux/epoll_pwait2.cpp
new file mode 100644
index 000000000000..671dede2a105
--- /dev/null
+++ b/src/sys/epoll/linux/epoll_pwait2.cpp
@@ -0,0 +1,44 @@
+//===---------- Linux implementation of the epoll_pwait2 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/sys/epoll/epoll_pwait2.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/sigset_t.h"
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+// #include "include/llvm-libc-types/struct_timespec.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, epoll_pwait2,
+ (int epfd, struct epoll_event *events, int maxevents,
+ const struct timespec *timeout, const sigset_t *sigmask)) {
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(
+ SYS_epoll_pwait2, epfd, reinterpret_cast<long>(events), maxevents,
+ reinterpret_cast<long>(timeout), reinterpret_cast<long>(sigmask),
+ sizeof(sigset_t));
+
+ // A negative return value indicates an error with the magnitude of the
+ // value being the error code.
+ if (ret < 0) {
+ libc_errno = -ret;
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/epoll/linux/epoll_wait.cpp b/src/sys/epoll/linux/epoll_wait.cpp
new file mode 100644
index 000000000000..0c43edf76454
--- /dev/null
+++ b/src/sys/epoll/linux/epoll_wait.cpp
@@ -0,0 +1,47 @@
+//===---------- Linux implementation of the epoll_wait 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/sys/epoll/epoll_wait.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+// TODO: Use this include once the include headers are also using quotes.
+// #include "include/llvm-libc-types/sigset_t.h"
+// #include "include/llvm-libc-types/struct_epoll_event.h"
+
+#include <sys/epoll.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, epoll_wait,
+ (int epfd, struct epoll_event *events, int maxevents,
+ int timeout)) {
+#ifdef SYS_epoll_wait
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(
+ SYS_epoll_wait, epfd, reinterpret_cast<long>(events), maxevents, timeout);
+#elif defined(SYS_epoll_pwait)
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(
+ SYS_epoll_pwait, epfd, reinterpret_cast<long>(events), maxevents, timeout,
+ reinterpret_cast<long>(nullptr), sizeof(sigset_t));
+#else
+#error "epoll_wait and epoll_pwait are unavailable. Unable to build epoll_wait."
+#endif
+ // A negative return value indicates an error with the magnitude of the
+ // value being the error code.
+ if (ret < 0) {
+ libc_errno = -ret;
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/mlock.cpp b/src/sys/mman/linux/mlock.cpp
new file mode 100644
index 000000000000..9bc5ab9a0786
--- /dev/null
+++ b/src/sys/mman/linux/mlock.cpp
@@ -0,0 +1,26 @@
+//===---------- Linux implementation of the mlock 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/sys/mman/mlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlock, (const void *addr, size_t len)) {
+ long ret = syscall_impl(SYS_mlock, cpp::bit_cast<long>(addr), len);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/mlock2.cpp b/src/sys/mman/linux/mlock2.cpp
new file mode 100644
index 000000000000..71b2b80d99bb
--- /dev/null
+++ b/src/sys/mman/linux/mlock2.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the mlock 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/sys/mman/mlock2.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+#ifdef SYS_mlock2
+LLVM_LIBC_FUNCTION(int, mlock2, (const void *addr, size_t len, int flags)) {
+ long ret = syscall_impl(SYS_mlock2, cpp::bit_cast<long>(addr), len, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+#endif
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/mlockall.cpp b/src/sys/mman/linux/mlockall.cpp
new file mode 100644
index 000000000000..c4af7d895273
--- /dev/null
+++ b/src/sys/mman/linux/mlockall.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the mlockall 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/sys/mman/mlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlockall, (int flags)) {
+ long ret = syscall_impl(SYS_mlockall, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/msync.cpp b/src/sys/mman/linux/msync.cpp
new file mode 100644
index 000000000000..1d2544f023c2
--- /dev/null
+++ b/src/sys/mman/linux/msync.cpp
@@ -0,0 +1,25 @@
+//===---------- Linux implementation of the msync 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/sys/mman/msync.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+LLVM_LIBC_FUNCTION(int, msync, (void *addr, size_t len, int flags)) {
+ long ret = syscall_impl(SYS_msync, cpp::bit_cast<long>(addr), len, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/munlock.cpp b/src/sys/mman/linux/munlock.cpp
new file mode 100644
index 000000000000..9ee50805ac30
--- /dev/null
+++ b/src/sys/mman/linux/munlock.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the munlock 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/sys/mman/munlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlock, (const void *addr, size_t len)) {
+ long ret = syscall_impl(SYS_munlock, cpp::bit_cast<long>(addr), len);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/munlockall.cpp b/src/sys/mman/linux/munlockall.cpp
new file mode 100644
index 000000000000..d1619d204a90
--- /dev/null
+++ b/src/sys/mman/linux/munlockall.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the munlockall 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/sys/mman/munlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlockall, (void)) {
+ long ret = syscall_impl(SYS_munlockall);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/shm_common.h b/src/sys/mman/linux/shm_common.h
new file mode 100644
index 000000000000..6f2a3fdc71b6
--- /dev/null
+++ b/src/sys/mman/linux/shm_common.h
@@ -0,0 +1,53 @@
+//===---------- Shared implementations for shm_open/shm_unlink ------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/array.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/errno/libc_errno.h"
+#include "src/string/memory_utils/inline_memcpy.h"
+
+// TODO: Get PATH_MAX via https://github.com/llvm/llvm-project/issues/85121
+#include <linux/limits.h>
+
+namespace LIBC_NAMESPACE {
+
+namespace shm_common {
+
+LIBC_INLINE_VAR constexpr cpp::string_view SHM_PREFIX = "/dev/shm/";
+using SHMPath = cpp::array<char, NAME_MAX + SHM_PREFIX.size() + 1>;
+
+LIBC_INLINE cpp::optional<SHMPath> translate_name(cpp::string_view name) {
+ // trim leading slashes
+ size_t offset = name.find_first_not_of('/');
+ if (offset == cpp::string_view::npos) {
+ libc_errno = EINVAL;
+ return cpp::nullopt;
+ }
+ name = name.substr(offset);
+
+ // check the name
+ if (name.size() > NAME_MAX) {
+ libc_errno = ENAMETOOLONG;
+ return cpp::nullopt;
+ }
+ if (name == "." || name == ".." || name.contains('/')) {
+ libc_errno = EINVAL;
+ return cpp::nullopt;
+ }
+
+ // prepend the prefix
+ SHMPath buffer;
+ inline_memcpy(buffer.data(), SHM_PREFIX.data(), SHM_PREFIX.size());
+ inline_memcpy(buffer.data() + SHM_PREFIX.size(), name.data(), name.size());
+ buffer[SHM_PREFIX.size() + name.size()] = '\0';
+ return buffer;
+}
+} // namespace shm_common
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/shm_open.cpp b/src/sys/mman/linux/shm_open.cpp
new file mode 100644
index 000000000000..0d39b8b4e53d
--- /dev/null
+++ b/src/sys/mman/linux/shm_open.cpp
@@ -0,0 +1,25 @@
+//===---------- Linux implementation of the shm_open 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/sys/mman/shm_open.h"
+#include "llvm-libc-macros/fcntl-macros.h"
+#include "src/fcntl/open.h"
+#include "src/sys/mman/linux/shm_common.h"
+
+namespace LIBC_NAMESPACE {
+
+static constexpr int DEFAULT_OFLAGS = O_NOFOLLOW | O_CLOEXEC | O_NONBLOCK;
+
+LLVM_LIBC_FUNCTION(int, shm_open, (const char *name, int oflags, mode_t mode)) {
+ using namespace shm_common;
+ if (cpp::optional<SHMPath> buffer = translate_name(name))
+ return open(buffer->data(), oflags | DEFAULT_OFLAGS, mode);
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/linux/shm_unlink.cpp b/src/sys/mman/linux/shm_unlink.cpp
new file mode 100644
index 000000000000..32f48d3e3e71
--- /dev/null
+++ b/src/sys/mman/linux/shm_unlink.cpp
@@ -0,0 +1,22 @@
+//===---------- Linux implementation of the shm_unlink 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/sys/mman/shm_unlink.h"
+#include "src/sys/mman/linux/shm_common.h"
+#include "src/unistd/unlink.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, shm_unlink, (const char *name)) {
+ using namespace shm_common;
+ if (cpp::optional<SHMPath> buffer = translate_name(name))
+ return unlink(buffer->data());
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/mman/mlock.h b/src/sys/mman/mlock.h
new file mode 100644
index 000000000000..73f329a0d52d
--- /dev/null
+++ b/src/sys/mman/mlock.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for mlock function ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE {
+
+int mlock(const void *addr, size_t len);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
diff --git a/src/sys/mman/mlock2.h b/src/sys/mman/mlock2.h
new file mode 100644
index 000000000000..872a7bfc5fba
--- /dev/null
+++ b/src/sys/mman/mlock2.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for mlock2 function ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE {
+
+#ifdef SYS_mlock2
+int mlock2(const void *addr, size_t len, int flags);
+#endif
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
diff --git a/src/sys/mman/mlockall.h b/src/sys/mman/mlockall.h
new file mode 100644
index 000000000000..bb4bd834310e
--- /dev/null
+++ b/src/sys/mman/mlockall.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for mlockall function -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int mlockall(int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
diff --git a/src/sys/mman/msync.h b/src/sys/mman/msync.h
new file mode 100644
index 000000000000..08afdd8c0628
--- /dev/null
+++ b/src/sys/mman/msync.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for msync function ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MSYNC_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MSYNC_H
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE {
+
+int msync(void *addr, size_t len, int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MSYNC_H
diff --git a/src/sys/mman/munlock.h b/src/sys/mman/munlock.h
new file mode 100644
index 000000000000..6aca82dae453
--- /dev/null
+++ b/src/sys/mman/munlock.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for munlock function --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int munlock(const void *addr, size_t len);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
diff --git a/src/sys/mman/munlockall.h b/src/sys/mman/munlockall.h
new file mode 100644
index 000000000000..5abd4b873465
--- /dev/null
+++ b/src/sys/mman/munlockall.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for munlockall function -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int munlockall(void);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
diff --git a/src/sys/mman/shm_open.h b/src/sys/mman/shm_open.h
new file mode 100644
index 000000000000..91796d7b5c05
--- /dev/null
+++ b/src/sys/mman/shm_open.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for shm_open function -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_SHM_OPEN_H
+#define LLVM_LIBC_SRC_SYS_MMAN_SHM_OPEN_H
+
+#include <llvm-libc-types/mode_t.h>
+
+namespace LIBC_NAMESPACE {
+
+int shm_open(const char *name, int oflag, mode_t mode);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_SHM_OPEN_H
diff --git a/src/sys/mman/shm_unlink.h b/src/sys/mman/shm_unlink.h
new file mode 100644
index 000000000000..c38c06adbaa2
--- /dev/null
+++ b/src/sys/mman/shm_unlink.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for shm_unlink function ------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_SHM_UNLINK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_SHM_UNLINK_H
+
+namespace LIBC_NAMESPACE {
+
+int shm_unlink(const char *name);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_SHM_UNLINK_H
diff --git a/src/sys/statvfs/fstatvfs.h b/src/sys/statvfs/fstatvfs.h
new file mode 100644
index 000000000000..6ca76a459ae5
--- /dev/null
+++ b/src/sys/statvfs/fstatvfs.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fstatvfs ----------------------*- 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_SYS_STATVFS_FSTATVFS_H
+#define LLVM_LIBC_SRC_SYS_STATVFS_FSTATVFS_H
+
+#include "llvm-libc-types/struct_statvfs.h"
+
+namespace LIBC_NAMESPACE {
+
+int fstatvfs(int fd, struct statvfs *buf);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_STATVFS_FSTATVFS_H
diff --git a/src/sys/statvfs/linux/fstatvfs.cpp b/src/sys/statvfs/linux/fstatvfs.cpp
new file mode 100644
index 000000000000..488989abbad7
--- /dev/null
+++ b/src/sys/statvfs/linux/fstatvfs.cpp
@@ -0,0 +1,26 @@
+//===-- Linux implementation of fstatvfs ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sys/statvfs/fstatvfs.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_assert.h"
+#include "src/sys/statvfs/linux/statfs_utils.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, fstatvfs, (int fd, struct statvfs *buf)) {
+ using namespace statfs_utils;
+ cpp::optional<LinuxStatFs> result = linux_fstatfs(fd);
+ if (result) {
+ LIBC_ASSERT(buf != nullptr);
+ *buf = statfs_to_statvfs(*result);
+ }
+ return result ? 0 : -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/statvfs/linux/statfs_utils.h b/src/sys/statvfs/linux/statfs_utils.h
new file mode 100644
index 000000000000..606786a57183
--- /dev/null
+++ b/src/sys/statvfs/linux/statfs_utils.h
@@ -0,0 +1,95 @@
+//===-- Convert Statfs to Statvfs -------------------------------*- 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_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
+#define LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
+
+#include "llvm-libc-types/struct_statvfs.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/macros/attributes.h"
+#include "src/errno/libc_errno.h"
+#include <asm/statfs.h>
+#include <sys/syscall.h>
+namespace LIBC_NAMESPACE {
+
+namespace statfs_utils {
+#ifdef SYS_statfs64
+using LinuxStatFs = statfs64;
+#else
+using LinuxStatFs = statfs;
+#endif
+
+// Linux kernel set an additional flag to f_flags. Libc should mask it out.
+LIBC_INLINE_VAR constexpr decltype(LinuxStatFs::f_flags) ST_VALID = 0x0020;
+
+LIBC_INLINE cpp::optional<LinuxStatFs> linux_statfs(const char *path) {
+ // The kernel syscall routine checks the validity of the path before filling
+ // the statfs structure. So, it is possible that the result is not initialized
+ // after the syscall. Since the struct is trvial, the compiler will generate
+ // pattern filling for the struct.
+ LinuxStatFs result;
+ // On 32-bit platforms, original statfs cannot handle large file systems.
+ // In such cases, SYS_statfs64 is defined and should be used.
+#ifdef SYS_statfs64
+ int ret = syscall_impl<int>(SYS_statfs64, path, sizeof(result), &result);
+#else
+ int ret = syscall_impl<int>(SYS_statfs, path, &result);
+#endif
+ if (ret < 0) {
+ libc_errno = -ret;
+ return cpp::nullopt;
+ }
+ result.f_flags &= ~ST_VALID;
+ return result;
+}
+
+LIBC_INLINE cpp::optional<LinuxStatFs> linux_fstatfs(int fd) {
+ // The kernel syscall routine checks the validity of the path before filling
+ // the statfs structure. So, it is possible that the result is not initialized
+ // after the syscall. Since the struct is trvial, the compiler will generate
+ // pattern filling for the struct.
+ LinuxStatFs result;
+ // On 32-bit platforms, original fstatfs cannot handle large file systems.
+ // In such cases, SYS_fstatfs64 is defined and should be used.
+#ifdef SYS_fstatfs64
+ int ret = syscall_impl<int>(SYS_fstatfs64, fd, sizeof(result), &result);
+#else
+ int ret = syscall_impl<int>(SYS_fstatfs, fd, &result);
+#endif
+ if (ret < 0) {
+ libc_errno = -ret;
+ return cpp::nullopt;
+ }
+ result.f_flags &= ~ST_VALID;
+ return result;
+}
+
+// must use 'struct' tag to refer to type 'statvfs' in this scope. There will be
+// a function in the same namespace with the same name. For consistency, we use
+// struct prefix for all statvfs/statfs related types.
+LIBC_INLINE struct statvfs statfs_to_statvfs(const LinuxStatFs &in) {
+ struct statvfs out;
+ out.f_bsize = in.f_bsize;
+ out.f_frsize = in.f_frsize;
+ out.f_blocks = in.f_blocks;
+ out.f_bfree = in.f_bfree;
+ out.f_bavail = in.f_bavail;
+ out.f_files = in.f_files;
+ out.f_ffree = in.f_ffree;
+ out.f_favail = in.f_ffree;
+ out.f_fsid = in.f_fsid.val[0] |
+ static_cast<decltype(out.f_fsid)>(in.f_fsid.val[1]) << 32;
+ out.f_flag = in.f_flags;
+ out.f_namemax = in.f_namelen;
+ return out;
+}
+} // namespace statfs_utils
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
diff --git a/src/sys/statvfs/linux/statvfs.cpp b/src/sys/statvfs/linux/statvfs.cpp
new file mode 100644
index 000000000000..a438ef1f0117
--- /dev/null
+++ b/src/sys/statvfs/linux/statvfs.cpp
@@ -0,0 +1,28 @@
+//===-- Linux implementation of statvfs -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/sys/statvfs/statvfs.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_assert.h"
+#include "src/sys/statvfs/linux/statfs_utils.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, statvfs,
+ (const char *__restrict path,
+ struct statvfs *__restrict buf)) {
+ using namespace statfs_utils;
+ cpp::optional<LinuxStatFs> result = linux_statfs(path);
+ if (result) {
+ LIBC_ASSERT(buf != nullptr);
+ *buf = statfs_to_statvfs(*result);
+ }
+ return result ? 0 : -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/sys/statvfs/statvfs.h b/src/sys/statvfs/statvfs.h
new file mode 100644
index 000000000000..792c7ddd0164
--- /dev/null
+++ b/src/sys/statvfs/statvfs.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for statvfs -----------------------*- 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_SYS_STATVFS_STATVFS_H
+#define LLVM_LIBC_SRC_SYS_STATVFS_STATVFS_H
+
+#include "llvm-libc-types/struct_statvfs.h"
+
+namespace LIBC_NAMESPACE {
+
+int statvfs(const char *__restrict path, struct statvfs *__restrict buf);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_STATVFS_STATVFS_H
diff --git a/src/time/gpu/nanosleep.cpp b/src/time/gpu/nanosleep.cpp
index e84fe622100e..dd669ff46c75 100644
--- a/src/time/gpu/nanosleep.cpp
+++ b/src/time/gpu/nanosleep.cpp
@@ -12,29 +12,31 @@
namespace LIBC_NAMESPACE {
-constexpr uint64_t TICKS_PER_NS = 1000000000UL;
+constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
LLVM_LIBC_FUNCTION(int, nanosleep,
(const struct timespec *req, struct timespec *rem)) {
if (!GPU_CLOCKS_PER_SEC || !req)
return -1;
- uint64_t nsecs = req->tv_nsec + req->tv_sec * TICKS_PER_NS;
+ uint64_t nsecs = req->tv_nsec + req->tv_sec * TICKS_PER_SEC;
+ uint64_t tick_rate = TICKS_PER_SEC / GPU_CLOCKS_PER_SEC;
uint64_t start = gpu::fixed_frequency_clock();
-#if defined(LIBC_TARGET_ARCH_IS_NVPTX) && __CUDA_ARCH__ >= 700
- uint64_t end = start + nsecs / (TICKS_PER_NS / GPU_CLOCKS_PER_SEC);
+#if defined(LIBC_TARGET_ARCH_IS_NVPTX)
+ uint64_t end = start + (nsecs + tick_rate - 1) / tick_rate;
uint64_t cur = gpu::fixed_frequency_clock();
// The NVPTX architecture supports sleeping and guaruntees the actual time
// slept will be somewhere between zero and twice the requested amount. Here
// we will sleep again if we undershot the time.
while (cur < end) {
- __nvvm_nanosleep(static_cast<uint32_t>(nsecs));
+ if (__nvvm_reflect("__CUDA_ARCH") >= 700)
+ LIBC_INLINE_ASM("nanosleep.u32 %0;" ::"r"(nsecs));
cur = gpu::fixed_frequency_clock();
nsecs -= nsecs > cur - start ? cur - start : 0;
}
#elif defined(LIBC_TARGET_ARCH_IS_AMDGPU)
- uint64_t end = start + nsecs / (TICKS_PER_NS / GPU_CLOCKS_PER_SEC);
+ uint64_t end = start + (nsecs + tick_rate - 1) / tick_rate;
uint64_t cur = gpu::fixed_frequency_clock();
// The AMDGPU architecture does not provide a sleep implementation with a
// known delay so we simply repeatedly sleep with a large value of ~960 clock
@@ -56,11 +58,11 @@ LLVM_LIBC_FUNCTION(int, nanosleep,
// Check to make sure we slept for at least the desired duration and set the
// remaining time if not.
- uint64_t elapsed = (stop - start) * (TICKS_PER_NS / GPU_CLOCKS_PER_SEC);
+ uint64_t elapsed = (stop - start) * tick_rate;
if (elapsed < nsecs) {
if (rem) {
- rem->tv_sec = (nsecs - elapsed) / TICKS_PER_NS;
- rem->tv_nsec = (nsecs - elapsed) % TICKS_PER_NS;
+ rem->tv_sec = (nsecs - elapsed) / TICKS_PER_SEC;
+ rem->tv_nsec = (nsecs - elapsed) % TICKS_PER_SEC;
}
return -1;
}
diff --git a/src/time/gpu/time_utils.h b/src/time/gpu/time_utils.h
index 531a748665b0..8a9a5f0f65b8 100644
--- a/src/time/gpu/time_utils.h
+++ b/src/time/gpu/time_utils.h
@@ -15,24 +15,13 @@ namespace LIBC_NAMESPACE {
#if defined(LIBC_TARGET_ARCH_IS_AMDGPU)
// AMDGPU does not have a single set frequency. Different architectures and
-// cards can have vary values. Here we default to a few known values, but for
-// complete support the frequency needs to be read from the kernel driver.
-#if defined(__GFX10__) || defined(__GFX11__) || defined(__GFX12__) || \
- defined(__gfx940__) || defined(__gfx941__) || defined(__gfx942__)
-// These architectures use a 100 MHz fixed frequency clock.
-constexpr uint64_t clock_freq = 100000000;
-#elif defined(__GFX9__)
-// These architectures use a 25 MHz fixed frequency clock expect for Vega 10
-// which is actually 27 Mhz. We default to 25 MHz in all cases anyway.
-constexpr uint64_t clock_freq = 25000000;
-#else
-// The frequency for these architecture is unknown. We simply default to zero.
-constexpr uint64_t clock_freq = 0;
-#endif
+// cards can have different values. The actualy frequency needs to be read from
+// the kernel driver and will be between 25 MHz and 100 MHz on most cards. All
+// cards following the GFX9 ISAs use a 100 MHz clock so we will default to that.
+constexpr uint64_t clock_freq = 100000000UL;
// We provide an externally visible symbol such that the runtime can set
-// this to the correct value. If it is not set we try to default to the
-// known values.
+// this to the correct value.
extern "C" [[gnu::visibility("protected")]] uint64_t
[[clang::address_space(4)]] __llvm_libc_clock_freq;
#define GPU_CLOCKS_PER_SEC static_cast<clock_t>(__llvm_libc_clock_freq)
diff --git a/src/unistd/_exit.cpp b/src/unistd/_exit.cpp
new file mode 100644
index 000000000000..6fbf3a51d42f
--- /dev/null
+++ b/src/unistd/_exit.cpp
@@ -0,0 +1,19 @@
+//===------------------- Implementation of _exit --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/unistd/_exit.h"
+#include "src/__support/OSUtil/quick_exit.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+[[noreturn]] LLVM_LIBC_FUNCTION(void, _exit, (int status)) {
+ quick_exit(status);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/unistd/_exit.h b/src/unistd/_exit.h
new file mode 100644
index 000000000000..141b87532189
--- /dev/null
+++ b/src/unistd/_exit.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for _exit -------------------------*- 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_UNISTD__EXIT_H
+#define LLVM_LIBC_SRC_UNISTD__EXIT_H
+
+namespace LIBC_NAMESPACE {
+
+[[noreturn]] void _exit(int status);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_UNISTD__EXIT_H
diff --git a/src/unistd/linux/pread.cpp b/src/unistd/linux/pread.cpp
index 614de9732c62..11cefc5c2f3a 100644
--- a/src/unistd/linux/pread.cpp
+++ b/src/unistd/linux/pread.cpp
@@ -10,7 +10,7 @@
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
-
+#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
#include "src/errno/libc_errno.h"
#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
@@ -28,6 +28,9 @@ LLVM_LIBC_FUNCTION(ssize_t, pread,
ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_pread64, fd, buf,
count, offset);
#endif
+ // The cast is important since there is a check that dereferences the pointer
+ // which fails on void*.
+ MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
if (ret < 0) {
libc_errno = static_cast<int>(-ret);
return -1;
diff --git a/src/unistd/linux/read.cpp b/src/unistd/linux/read.cpp
index 691a236982e3..41be1eb10c0d 100644
--- a/src/unistd/linux/read.cpp
+++ b/src/unistd/linux/read.cpp
@@ -10,7 +10,7 @@
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
-
+#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
#include "src/errno/libc_errno.h"
#include <sys/syscall.h> // For syscall numbers.
@@ -22,6 +22,9 @@ LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) {
libc_errno = static_cast<int>(-ret);
return -1;
}
+ // The cast is important since there is a check that dereferences the pointer
+ // which fails on void*.
+ MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
return ret;
}
diff --git a/test/IntegrationTest/test.h b/test/IntegrationTest/test.h
index c015bb44586f..64906ef17939 100644
--- a/test/IntegrationTest/test.h
+++ b/test/IntegrationTest/test.h
@@ -68,9 +68,12 @@
////////////////////////////////////////////////////////////////////////////////
// Errno checks.
-#define ASSERT_ERRNO_EQ(VAL) ASSERT_EQ(VAL, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_SUCCESS() ASSERT_EQ(0, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_FAILURE() ASSERT_NE(0, static_cast<int>(libc_errno))
+#define ASSERT_ERRNO_EQ(VAL) \
+ ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_SUCCESS() \
+ ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_FAILURE() \
+ ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
// Integration tests are compiled with -ffreestanding which stops treating
// the main function as a non-overloadable special function. Hence, we use a
diff --git a/test/UnitTest/ErrnoSetterMatcher.h b/test/UnitTest/ErrnoSetterMatcher.h
index 6b15bd4e9b79..745ba4182023 100644
--- a/test/UnitTest/ErrnoSetterMatcher.h
+++ b/test/UnitTest/ErrnoSetterMatcher.h
@@ -109,8 +109,8 @@ public:
bool match(T got) {
actual_return = got;
- actual_errno = libc_errno;
- libc_errno = 0;
+ actual_errno = LIBC_NAMESPACE::libc_errno;
+ LIBC_NAMESPACE::libc_errno = 0;
if constexpr (ignore_errno())
return return_cmp.compare(actual_return);
else
diff --git a/test/UnitTest/ExecuteFunction.h b/test/UnitTest/ExecuteFunction.h
index 2129e63a3a00..95950567e74a 100644
--- a/test/UnitTest/ExecuteFunction.h
+++ b/test/UnitTest/ExecuteFunction.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_TESTUTILS_EXECUTEFUNCTION_H
-#define LLVM_LIBC_UTILS_TESTUTILS_EXECUTEFUNCTION_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_EXECUTEFUNCTION_H
+#define LLVM_LIBC_TEST_UNITTEST_EXECUTEFUNCTION_H
#include <stdint.h>
@@ -49,4 +49,4 @@ const char *signal_as_string(int signum);
} // namespace testutils
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_UTILS_TESTUTILS_EXECUTEFUNCTION_H
+#endif // LLVM_LIBC_TEST_UNITTEST_EXECUTEFUNCTION_H
diff --git a/test/UnitTest/FPExceptMatcher.h b/test/UnitTest/FPExceptMatcher.h
index 98c4f737d172..d36e98d22d4b 100644
--- a/test/UnitTest/FPExceptMatcher.h
+++ b/test/UnitTest/FPExceptMatcher.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_FPEXCEPTMATCHER_H
-#define LLVM_LIBC_UTILS_UNITTEST_FPEXCEPTMATCHER_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
+#define LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
#ifndef LIBC_COPT_TEST_USE_FUCHSIA
@@ -61,4 +61,4 @@ public:
#define ASSERT_RAISES_FP_EXCEPT(func) ASSERT_DEATH(func, WITH_SIGNAL(SIGFPE))
#endif // LIBC_COPT_TEST_USE_FUCHSIA
-#endif // LLVM_LIBC_UTILS_UNITTEST_FPEXCEPTMATCHER_H
+#endif // LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
diff --git a/test/UnitTest/FPMatcher.h b/test/UnitTest/FPMatcher.h
index 210690a9c6ec..f4553eac5c8a 100644
--- a/test/UnitTest/FPMatcher.h
+++ b/test/UnitTest/FPMatcher.h
@@ -6,9 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
-#define LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
+#define LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
+#include "src/__support/CPP/array.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
@@ -17,7 +18,7 @@
#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace LIBC_NAMESPACE {
namespace testing {
@@ -63,7 +64,6 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) {
template <typename T> struct FPTest : public Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
static constexpr StorageType STORAGE_MAX =
LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();
static constexpr T zero = FPBits::zero(Sign::POS).get_val();
@@ -92,7 +92,7 @@ template <typename T> struct FPTest : public Test {
#define DECLARE_SPECIAL_CONSTANTS(T) \
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; \
using StorageType = typename FPBits::StorageType; \
- using Sign = LIBC_NAMESPACE::fputil::Sign; \
+ \
static constexpr StorageType STORAGE_MAX = \
LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max(); \
const T zero = FPBits::zero(Sign::POS).get_val(); \
@@ -102,9 +102,18 @@ template <typename T> struct FPTest : public Test {
const T inf = FPBits::inf(Sign::POS).get_val(); \
const T neg_inf = FPBits::inf(Sign::NEG).get_val(); \
const T min_normal = FPBits::min_normal().get_val(); \
- const T max_normal = FPBits::max_normal().get_val(); \
- const T min_denormal = FPBits::min_subnormal().get_val(); \
- const T max_denormal = FPBits::max_subnormal().get_val();
+ const T max_normal = FPBits::max_normal(Sign::POS).get_val(); \
+ const T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val(); \
+ const T min_denormal = FPBits::min_subnormal(Sign::POS).get_val(); \
+ const T neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val(); \
+ const T max_denormal = FPBits::max_subnormal().get_val(); \
+ static constexpr int UNKNOWN_MATH_ROUNDING_DIRECTION = 99; \
+ static constexpr LIBC_NAMESPACE::cpp::array<int, 6> \
+ MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN = { \
+ FP_INT_UPWARD, FP_INT_DOWNWARD, \
+ FP_INT_TOWARDZERO, FP_INT_TONEARESTFROMZERO, \
+ FP_INT_TONEAREST, UNKNOWN_MATH_ROUNDING_DIRECTION, \
+ };
#define EXPECT_FP_EQ(expected, actual) \
EXPECT_THAT(actual, LIBC_NAMESPACE::testing::getMatcher< \
@@ -132,8 +141,8 @@ template <typename T> struct FPTest : public Test {
#define EXPECT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
- int actual = libc_errno; \
- libc_errno = 0; \
+ int actual = LIBC_NAMESPACE::libc_errno; \
+ LIBC_NAMESPACE::libc_errno = 0; \
EXPECT_EQ(actual, expected); \
} \
} while (0)
@@ -141,8 +150,8 @@ template <typename T> struct FPTest : public Test {
#define ASSERT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
- int actual = libc_errno; \
- libc_errno = 0; \
+ int actual = LIBC_NAMESPACE::libc_errno; \
+ LIBC_NAMESPACE::libc_errno = 0; \
ASSERT_EQ(actual, expected); \
} \
} while (0)
@@ -210,4 +219,4 @@ template <typename T> struct FPTest : public Test {
} \
} while (0)
-#endif // LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
+#endif // LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
diff --git a/test/UnitTest/FuchsiaTest.h b/test/UnitTest/FuchsiaTest.h
index 1b7537965813..e9e8348ee5dd 100644
--- a/test/UnitTest/FuchsiaTest.h
+++ b/test/UnitTest/FuchsiaTest.h
@@ -14,9 +14,12 @@
#define WITH_SIGNAL(X) #X
// These macros are used in string unittests.
-#define ASSERT_ERRNO_EQ(VAL) ASSERT_EQ(VAL, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_SUCCESS() ASSERT_EQ(0, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_FAILURE() ASSERT_NE(0, static_cast<int>(libc_errno))
+#define ASSERT_ERRNO_EQ(VAL) \
+ ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_SUCCESS() \
+ ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_FAILURE() \
+ ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
#ifndef EXPECT_DEATH
// Since zxtest has ASSERT_DEATH but not EXPECT_DEATH, wrap calling it
diff --git a/test/UnitTest/LibcTest.cpp b/test/UnitTest/LibcTest.cpp
index 201b40a178dc..03cd25191ecd 100644
--- a/test/UnitTest/LibcTest.cpp
+++ b/test/UnitTest/LibcTest.cpp
@@ -8,9 +8,12 @@
#include "LibcTest.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/UInt128.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/TestLogger.h"
#if __STDC_HOSTED__
@@ -36,7 +39,8 @@ TestLogger &operator<<(TestLogger &logger, Location Loc) {
// When the value is UInt128, __uint128_t or wider, show its hexadecimal
// digits.
template <typename T>
-cpp::enable_if_t<cpp::is_integral_v<T> && (sizeof(T) > sizeof(uint64_t)),
+cpp::enable_if_t<(cpp::is_integral_v<T> && (sizeof(T) > sizeof(uint64_t))) ||
+ is_big_int_v<T>,
cpp::string>
describeValue(T Value) {
static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt");
@@ -45,14 +49,24 @@ describeValue(T Value) {
}
// When the value is of a standard integral type, just display it as normal.
-template <typename ValType>
-cpp::enable_if_t<cpp::is_integral_v<ValType> &&
- sizeof(ValType) <= sizeof(uint64_t),
+template <typename T>
+cpp::enable_if_t<cpp::is_integral_v<T> && (sizeof(T) <= sizeof(uint64_t)),
cpp::string>
-describeValue(ValType Value) {
+describeValue(T Value) {
return cpp::to_string(Value);
}
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+template <typename T>
+cpp::enable_if_t<cpp::is_fixed_point_v<T>, cpp::string> describeValue(T Value) {
+ using FXRep = fixed_point::FXRep<T>;
+ using comp_t = typename FXRep::CompType;
+
+ return cpp::to_string(cpp::bit_cast<comp_t>(Value)) + " * 2^-" +
+ cpp::to_string(FXRep::FRACTION_LEN);
+}
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
cpp::string_view describeValue(const cpp::string &Value) { return Value; }
cpp::string_view describeValue(cpp::string_view Value) { return Value; }
@@ -181,99 +195,58 @@ int Test::runTests(const char *TestFilter) {
namespace internal {
-template bool test<char>(RunContext *Ctx, TestCond Cond, char LHS, char RHS,
- const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<short>(RunContext *Ctx, TestCond Cond, short LHS, short RHS,
- const char *LHSStr, const char *RHSStr, Location Loc);
+#define TEST_SPECIALIZATION(TYPE) \
+ template bool test<TYPE>(RunContext * Ctx, TestCond Cond, TYPE LHS, \
+ TYPE RHS, const char *LHSStr, const char *RHSStr, \
+ Location Loc)
-template bool test<int>(RunContext *Ctx, TestCond Cond, int LHS, int RHS,
- const char *LHSStr, const char *RHSStr, Location Loc);
+TEST_SPECIALIZATION(char);
+TEST_SPECIALIZATION(short);
+TEST_SPECIALIZATION(int);
+TEST_SPECIALIZATION(long);
+TEST_SPECIALIZATION(long long);
-template bool test<long>(RunContext *Ctx, TestCond Cond, long LHS, long RHS,
- const char *LHSStr, const char *RHSStr, Location Loc);
+TEST_SPECIALIZATION(unsigned char);
+TEST_SPECIALIZATION(unsigned short);
+TEST_SPECIALIZATION(unsigned int);
+TEST_SPECIALIZATION(unsigned long);
+TEST_SPECIALIZATION(unsigned long long);
-template bool test<long long>(RunContext *Ctx, TestCond Cond, long long LHS,
- long long RHS, const char *LHSStr,
- const char *RHSStr, Location Loc);
-
-template bool test<unsigned char>(RunContext *Ctx, TestCond Cond,
- unsigned char LHS, unsigned char RHS,
- const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<unsigned short>(RunContext *Ctx, TestCond Cond,
- unsigned short LHS, unsigned short RHS,
- const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<unsigned int>(RunContext *Ctx, TestCond Cond,
- unsigned int LHS, unsigned int RHS,
- const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<unsigned long>(RunContext *Ctx, TestCond Cond,
- unsigned long LHS, unsigned long RHS,
- const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<bool>(RunContext *Ctx, TestCond Cond, bool LHS, bool RHS,
- const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<unsigned long long>(RunContext *Ctx, TestCond Cond,
- unsigned long long LHS,
- unsigned long long RHS,
- const char *LHSStr, const char *RHSStr,
- Location Loc);
+TEST_SPECIALIZATION(bool);
// We cannot just use a single UInt128 specialization as that resolves to only
// one type, UInt<128> or __uint128_t. We want both overloads as we want to
-// be able to unittest UInt<128> on platforms where UInt128 resolves to
-// UInt128.
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
// When builtin __uint128_t type is available, include its specialization
// also.
-template bool test<__uint128_t>(RunContext *Ctx, TestCond Cond, __uint128_t LHS,
- __uint128_t RHS, const char *LHSStr,
- const char *RHSStr, Location Loc);
-#endif
-
-template bool test<LIBC_NAMESPACE::cpp::Int<128>>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::Int<128> LHS,
- LIBC_NAMESPACE::cpp::Int<128> RHS, const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<128>>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<128> LHS,
- LIBC_NAMESPACE::cpp::UInt<128> RHS, const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<192>>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<192> LHS,
- LIBC_NAMESPACE::cpp::UInt<192> RHS, const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<256>>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<256> LHS,
- LIBC_NAMESPACE::cpp::UInt<256> RHS, const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<320>>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<320> LHS,
- LIBC_NAMESPACE::cpp::UInt<320> RHS, const char *LHSStr, const char *RHSStr,
- Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::string_view>(
- RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::string_view LHS,
- LIBC_NAMESPACE::cpp::string_view RHS, const char *LHSStr,
- const char *RHSStr, Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::string>(RunContext *Ctx, TestCond Cond,
- LIBC_NAMESPACE::cpp::string LHS,
- LIBC_NAMESPACE::cpp::string RHS,
- const char *LHSStr,
- const char *RHSStr,
- Location Loc);
+TEST_SPECIALIZATION(__uint128_t);
+#endif // LIBC_TYPES_HAS_INT128
+
+TEST_SPECIALIZATION(LIBC_NAMESPACE::Int<128>);
+
+TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<128>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<192>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<256>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<320>);
+
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string_view);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string);
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+TEST_SPECIALIZATION(short fract);
+TEST_SPECIALIZATION(fract);
+TEST_SPECIALIZATION(long fract);
+TEST_SPECIALIZATION(unsigned short fract);
+TEST_SPECIALIZATION(unsigned fract);
+TEST_SPECIALIZATION(unsigned long fract);
+
+TEST_SPECIALIZATION(short accum);
+TEST_SPECIALIZATION(accum);
+TEST_SPECIALIZATION(long accum);
+TEST_SPECIALIZATION(unsigned short accum);
+TEST_SPECIALIZATION(unsigned accum);
+TEST_SPECIALIZATION(unsigned long accum);
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
} // namespace internal
diff --git a/test/UnitTest/LibcTest.h b/test/UnitTest/LibcTest.h
index 1a90d10d7ec0..a813a59d2d67 100644
--- a/test/UnitTest/LibcTest.h
+++ b/test/UnitTest/LibcTest.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_LIBCTEST_H
-#define LLVM_LIBC_UTILS_UNITTEST_LIBCTEST_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_LIBCTEST_H
+#define LLVM_LIBC_TEST_UNITTEST_LIBCTEST_H
// This is defined as a simple macro in test.h so that it exists for platforms
// that don't use our test infrastructure. It's defined as a proper function
@@ -125,8 +125,11 @@ protected:
// is the result of the |Cond| operation on |LHS| and |RHS|. Though not bad,
// |Cond| on mismatched |LHS| and |RHS| types can potentially succeed because
// of type promotion.
- template <typename ValType,
- cpp::enable_if_t<cpp::is_integral_v<ValType>, int> = 0>
+ template <
+ typename ValType,
+ cpp::enable_if_t<cpp::is_integral_v<ValType> || is_big_int_v<ValType> ||
+ cpp::is_fixed_point_v<ValType>,
+ int> = 0>
bool test(TestCond Cond, ValType LHS, ValType RHS, const char *LHSStr,
const char *RHSStr, internal::Location Loc) {
return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, Loc);
@@ -446,9 +449,12 @@ CString libc_make_test_file_path_func(const char *file_name);
////////////////////////////////////////////////////////////////////////////////
// Errno checks.
-#define ASSERT_ERRNO_EQ(VAL) ASSERT_EQ(VAL, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_SUCCESS() ASSERT_EQ(0, static_cast<int>(libc_errno))
-#define ASSERT_ERRNO_FAILURE() ASSERT_NE(0, static_cast<int>(libc_errno))
+#define ASSERT_ERRNO_EQ(VAL) \
+ ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_SUCCESS() \
+ ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_FAILURE() \
+ ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
////////////////////////////////////////////////////////////////////////////////
// Subprocess checks.
@@ -488,4 +494,4 @@ CString libc_make_test_file_path_func(const char *file_name);
#define WITH_SIGNAL(X) X
-#endif // LLVM_LIBC_UTILS_UNITTEST_LIBCTEST_H
+#endif // LLVM_LIBC_TEST_UNITTEST_LIBCTEST_H
diff --git a/test/UnitTest/MemoryMatcher.h b/test/UnitTest/MemoryMatcher.h
index cf861a6757ae..c548bafb7ae4 100644
--- a/test/UnitTest/MemoryMatcher.h
+++ b/test/UnitTest/MemoryMatcher.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_MEMORY_MATCHER_H
-#define LLVM_LIBC_UTILS_UNITTEST_MEMORY_MATCHER_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_MEMORYMATCHER_H
+#define LLVM_LIBC_TEST_UNITTEST_MEMORYMATCHER_H
#include "src/__support/CPP/span.h"
@@ -66,4 +66,4 @@ public:
#endif
-#endif // LLVM_LIBC_UTILS_UNITTEST_MEMORY_MATCHER_H
+#endif // LLVM_LIBC_TEST_UNITTEST_MEMORYMATCHER_H
diff --git a/test/UnitTest/PlatformDefs.h b/test/UnitTest/PlatformDefs.h
index 40472f4eb4eb..f9911b155769 100644
--- a/test/UnitTest/PlatformDefs.h
+++ b/test/UnitTest/PlatformDefs.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_PLATFORMDEFS_H
-#define LLVM_LIBC_UTILS_UNITTEST_PLATFORMDEFS_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_PLATFORMDEFS_H
+#define LLVM_LIBC_TEST_UNITTEST_PLATFORMDEFS_H
#if !defined(_WIN32)
#define ENABLE_SUBPROCESS_TESTS
#endif
-#endif // LLVM_LIBC_UTILS_UNITTEST_PLATFORMDEFS_H
+#endif // LLVM_LIBC_TEST_UNITTEST_PLATFORMDEFS_H
diff --git a/test/UnitTest/PrintfMatcher.cpp b/test/UnitTest/PrintfMatcher.cpp
index 32f3be73307e..c8303815c922 100644
--- a/test/UnitTest/PrintfMatcher.cpp
+++ b/test/UnitTest/PrintfMatcher.cpp
@@ -39,6 +39,10 @@ namespace {
case (LengthModifier::lm): \
tlog << #lm; \
break
+#define CASE_LM_BIT_WIDTH(lm, bw) \
+ case (LengthModifier::lm): \
+ tlog << #lm << "\n\tbit width: :" << bw; \
+ break
static void display(FormatSection form) {
tlog << "Raw String (len " << form.raw_string.size() << "): \"";
@@ -67,6 +71,8 @@ static void display(FormatSection form) {
CASE_LM(z);
CASE_LM(t);
CASE_LM(L);
+ CASE_LM_BIT_WIDTH(w, form.bit_width);
+ CASE_LM_BIT_WIDTH(wf, form.bit_width);
}
tlog << "\n";
tlog << "\tconversion name: " << form.conv_name << "\n";
diff --git a/test/UnitTest/RoundingModeUtils.h b/test/UnitTest/RoundingModeUtils.h
index d1c3c6ff400a..b986c98fa2e5 100644
--- a/test/UnitTest/RoundingModeUtils.h
+++ b/test/UnitTest/RoundingModeUtils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_TESTUTILS_ROUNDINGMODEUTILS_H
-#define LLVM_LIBC_UTILS_TESTUTILS_ROUNDINGMODEUTILS_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_ROUNDINGMODEUTILS_H
+#define LLVM_LIBC_TEST_UNITTEST_ROUNDINGMODEUTILS_H
#include <stdint.h>
@@ -34,4 +34,4 @@ template <RoundingMode R> struct ForceRoundingModeTest : ForceRoundingMode {
} // namespace fputil
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_UTILS_TESTUTILS_ROUNDINGMODEUTILS_H
+#endif // LLVM_LIBC_TEST_UNITTEST_ROUNDINGMODEUTILS_H
diff --git a/test/UnitTest/StringUtils.h b/test/UnitTest/StringUtils.h
index ac28926d51cd..cab0b58f9690 100644
--- a/test/UnitTest/StringUtils.h
+++ b/test/UnitTest/StringUtils.h
@@ -6,17 +6,18 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
-#define LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_STRINGUTILS_H
+#define LLVM_LIBC_TEST_UNITTEST_STRINGUTILS_H
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/UInt.h"
namespace LIBC_NAMESPACE {
// Return the first N hex digits of an integer as a string in upper case.
template <typename T>
-cpp::enable_if_t<cpp::is_integral_v<T>, cpp::string>
+cpp::enable_if_t<cpp::is_integral_v<T> || is_big_int_v<T>, cpp::string>
int_to_hex(T value, size_t length = sizeof(T) * 2) {
cpp::string s(length, '0');
@@ -33,4 +34,4 @@ int_to_hex(T value, size_t length = sizeof(T) * 2) {
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
+#endif // LLVM_LIBC_TEST_UNITTEST_STRINGUTILS_H
diff --git a/test/UnitTest/Test.h b/test/UnitTest/Test.h
index 61021b9d0e13..f7ce3cfa5cf6 100644
--- a/test/UnitTest/Test.h
+++ b/test/UnitTest/Test.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_TEST_H
-#define LLVM_LIBC_UTILS_UNITTEST_TEST_H
+#ifndef LLVM_LIBC_TEST_UNITTEST_TEST_H
+#define LLVM_LIBC_TEST_UNITTEST_TEST_H
// This macro takes a file name and returns a value implicitly castable to
// a const char*. That const char* is the path to a file with the provided name
@@ -24,4 +24,4 @@
#include "LibcTest.h"
#endif
-#endif // LLVM_LIBC_UTILS_UNITTEST_TEST_H
+#endif // LLVM_LIBC_TEST_UNITTEST_TEST_H
diff --git a/test/UnitTest/TestLogger.cpp b/test/UnitTest/TestLogger.cpp
index 6bb0e17dc388..4756188b46cb 100644
--- a/test/UnitTest/TestLogger.cpp
+++ b/test/UnitTest/TestLogger.cpp
@@ -2,7 +2,9 @@
#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/UInt.h" // is_big_int
#include "src/__support/UInt128.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include <stdint.h>
@@ -47,8 +49,9 @@ template <> TestLogger &TestLogger::operator<<(void *addr) {
}
template <typename T> TestLogger &TestLogger::operator<<(T t) {
- if constexpr (cpp::is_integral_v<T> && cpp::is_unsigned_v<T> &&
- sizeof(T) > sizeof(uint64_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();
@@ -68,15 +71,15 @@ template TestLogger &TestLogger::operator<< <unsigned short>(unsigned short);
template TestLogger &TestLogger::operator<< <unsigned int>(unsigned int);
template TestLogger &TestLogger::operator<< <unsigned long>(unsigned long);
template TestLogger &
-TestLogger::operator<< <unsigned long long>(unsigned long long);
+ TestLogger::operator<< <unsigned long long>(unsigned long long);
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
template TestLogger &TestLogger::operator<< <__uint128_t>(__uint128_t);
-#endif
-template TestLogger &TestLogger::operator<< <cpp::UInt<128>>(cpp::UInt<128>);
-template TestLogger &TestLogger::operator<< <cpp::UInt<192>>(cpp::UInt<192>);
-template TestLogger &TestLogger::operator<< <cpp::UInt<256>>(cpp::UInt<256>);
-template TestLogger &TestLogger::operator<< <cpp::UInt<320>>(cpp::UInt<320>);
+#endif // LIBC_TYPES_HAS_INT128
+template TestLogger &TestLogger::operator<< <UInt<128>>(UInt<128>);
+template TestLogger &TestLogger::operator<< <UInt<192>>(UInt<192>);
+template TestLogger &TestLogger::operator<< <UInt<256>>(UInt<256>);
+template TestLogger &TestLogger::operator<< <UInt<320>>(UInt<320>);
// TODO: Add floating point formatting once it's supported by StringStream.
diff --git a/test/include/stdbit_stub.h b/test/include/stdbit_stub.h
new file mode 100644
index 000000000000..65b1ca3b2c29
--- /dev/null
+++ b/test/include/stdbit_stub.h
@@ -0,0 +1,73 @@
+//===-- Utilities for testing stdbit --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+/*
+ * Declare these BEFORE including stdbit-macros.h so that this test may still be
+ * run even if a given target doesn't yet have these individual entrypoints
+ * enabled.
+ */
+
+#include "include/__llvm-libc-common.h"
+
+#include <stdbool.h> // bool in C
+
+#define STDBIT_STUB_FUNCTION(FUNC_NAME, LEADING_VAL) \
+ unsigned FUNC_NAME##_uc(unsigned char x) __NOEXCEPT { \
+ return LEADING_VAL##AU; \
+ } \
+ unsigned FUNC_NAME##_us(unsigned short x) __NOEXCEPT { \
+ return LEADING_VAL##BU; \
+ } \
+ unsigned FUNC_NAME##_ui(unsigned int x) __NOEXCEPT { \
+ return LEADING_VAL##CU; \
+ } \
+ unsigned FUNC_NAME##_ul(unsigned long x) __NOEXCEPT { \
+ return LEADING_VAL##DU; \
+ } \
+ unsigned FUNC_NAME##_ull(unsigned long long x) __NOEXCEPT { \
+ return LEADING_VAL##EU; \
+ }
+
+__BEGIN_C_DECLS
+
+STDBIT_STUB_FUNCTION(stdc_leading_zeros, 0xA)
+STDBIT_STUB_FUNCTION(stdc_leading_ones, 0xB)
+STDBIT_STUB_FUNCTION(stdc_trailing_zeros, 0xC)
+STDBIT_STUB_FUNCTION(stdc_trailing_ones, 0xD)
+STDBIT_STUB_FUNCTION(stdc_first_leading_zero, 0xE)
+STDBIT_STUB_FUNCTION(stdc_first_leading_one, 0xF)
+STDBIT_STUB_FUNCTION(stdc_first_trailing_zero, 0x0)
+STDBIT_STUB_FUNCTION(stdc_first_trailing_one, 0x1)
+STDBIT_STUB_FUNCTION(stdc_count_zeros, 0x2)
+STDBIT_STUB_FUNCTION(stdc_count_ones, 0x3)
+
+bool stdc_has_single_bit_uc(unsigned char x) __NOEXCEPT { return false; }
+bool stdc_has_single_bit_us(unsigned short x) __NOEXCEPT { return false; }
+bool stdc_has_single_bit_ui(unsigned x) __NOEXCEPT { return false; }
+bool stdc_has_single_bit_ul(unsigned long x) __NOEXCEPT { return false; }
+bool stdc_has_single_bit_ull(unsigned long long x) __NOEXCEPT { return false; }
+
+STDBIT_STUB_FUNCTION(stdc_bit_width, 0x4)
+
+unsigned char stdc_bit_floor_uc(unsigned char x) __NOEXCEPT { return 0x5AU; }
+unsigned short stdc_bit_floor_us(unsigned short x) __NOEXCEPT { return 0x5BU; }
+unsigned stdc_bit_floor_ui(unsigned x) __NOEXCEPT { return 0x5CU; }
+unsigned long stdc_bit_floor_ul(unsigned long x) __NOEXCEPT { return 0x5DUL; }
+unsigned long long stdc_bit_floor_ull(unsigned long long x) __NOEXCEPT {
+ return 0x5EULL;
+}
+
+unsigned char stdc_bit_ceil_uc(unsigned char x) __NOEXCEPT { return 0x6AU; }
+unsigned short stdc_bit_ceil_us(unsigned short x) __NOEXCEPT { return 0x6BU; }
+unsigned stdc_bit_ceil_ui(unsigned x) __NOEXCEPT { return 0x6CU; }
+unsigned long stdc_bit_ceil_ul(unsigned long x) __NOEXCEPT { return 0x6DUL; }
+unsigned long long stdc_bit_ceil_ull(unsigned long long x) __NOEXCEPT {
+ return 0x6EULL;
+}
+
+__END_C_DECLS
diff --git a/test/include/stdbit_test.c b/test/include/stdbit_test.c
new file mode 100644
index 000000000000..e278e9a7374e
--- /dev/null
+++ b/test/include/stdbit_test.c
@@ -0,0 +1,61 @@
+//===-- Unittests for stdbit ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+/*
+ * The intent of this test is validate that:
+ * 1. We provide the definition of the various type generic macros of stdbit.h
+ * (the macros are transitively included from stdbit-macros.h by stdbit.h).
+ * 2. It dispatches to the correct underlying function.
+ * Because unit tests build without public packaging, the object files produced
+ * do not contain non-namespaced symbols.
+ */
+
+/*
+ * Declare these BEFORE including stdbit-macros.h so that this test may still be
+ * run even if a given target doesn't yet have these individual entrypoints
+ * enabled.
+ */
+#include "stdbit_stub.h"
+
+#include "include/llvm-libc-macros/stdbit-macros.h"
+
+#include <assert.h>
+
+#define CHECK_FUNCTION(FUNC_NAME, VAL) \
+ do { \
+ assert(FUNC_NAME((unsigned char)0U) == VAL##AU); \
+ assert(FUNC_NAME((unsigned short)0U) == VAL##BU); \
+ assert(FUNC_NAME(0U) == VAL##CU); \
+ assert(FUNC_NAME(0UL) == VAL##DU); \
+ assert(FUNC_NAME(0ULL) == VAL##EU); \
+ } while (0)
+
+int main(void) {
+ CHECK_FUNCTION(stdc_leading_zeros, 0xA);
+ CHECK_FUNCTION(stdc_leading_ones, 0xB);
+ CHECK_FUNCTION(stdc_trailing_zeros, 0xC);
+ CHECK_FUNCTION(stdc_trailing_ones, 0xD);
+ CHECK_FUNCTION(stdc_first_leading_zero, 0xE);
+ CHECK_FUNCTION(stdc_first_leading_one, 0xF);
+ CHECK_FUNCTION(stdc_first_trailing_zero, 0x0);
+ CHECK_FUNCTION(stdc_first_trailing_one, 0x1);
+ CHECK_FUNCTION(stdc_count_zeros, 0x2);
+ CHECK_FUNCTION(stdc_count_ones, 0x3);
+
+ assert(!stdc_has_single_bit((unsigned char)1U));
+ assert(!stdc_has_single_bit((unsigned short)1U));
+ assert(!stdc_has_single_bit(1U));
+ assert(!stdc_has_single_bit(1UL));
+ assert(!stdc_has_single_bit(1ULL));
+
+ CHECK_FUNCTION(stdc_bit_width, 0x4);
+ CHECK_FUNCTION(stdc_bit_floor, 0x5);
+ CHECK_FUNCTION(stdc_bit_ceil, 0x6);
+
+ return 0;
+}
diff --git a/test/include/stdbit_test.cpp b/test/include/stdbit_test.cpp
index d20005cc31af..bee1a19f9c03 100644
--- a/test/include/stdbit_test.cpp
+++ b/test/include/stdbit_test.cpp
@@ -8,28 +8,153 @@
#include "test/UnitTest/Test.h"
-#include <stdbit.h>
-
/*
* The intent of this test is validate that:
- * 1. We provide the definition of the various type generic macros of stdbit.h.
+ * 1. We provide the definition of the various type generic macros of stdbit.h
+ * (the macros are transitively included from stdbit-macros.h by stdbit.h).
* 2. It dispatches to the correct underlying function.
* Because unit tests build without public packaging, the object files produced
* do not contain non-namespaced symbols.
*/
-unsigned char stdc_leading_zeros_uc(unsigned char) { return 0xAA; }
-unsigned short stdc_leading_zeros_us(unsigned short) { return 0xAB; }
-unsigned stdc_leading_zeros_ui(unsigned) { return 0xAC; }
-unsigned long stdc_leading_zeros_ul(unsigned long) { return 0xAD; }
-unsigned long long stdc_leading_zeros_ull(unsigned long long) { return 0xAF; }
-
-TEST(LlvmLibcStdbitTest, TypeGenericMacro) {
- EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned char>(0U)),
- static_cast<unsigned char>(0xAA));
- EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned short>(0U)),
- static_cast<unsigned short>(0xAB));
- EXPECT_EQ(stdc_leading_zeros(0U), static_cast<unsigned>(0xAC));
- EXPECT_EQ(stdc_leading_zeros(0UL), static_cast<unsigned long>(0xAD));
- EXPECT_EQ(stdc_leading_zeros(0ULL), static_cast<unsigned long long>(0xAF));
+/*
+ * Declare these BEFORE including stdbit-macros.h so that this test may still be
+ * run even if a given target doesn't yet have these individual entrypoints
+ * enabled.
+ */
+#include "stdbit_stub.h"
+
+#include "include/llvm-libc-macros/stdbit-macros.h"
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroLeadingZeros) {
+ EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned char>(0U)), 0xAAU);
+ EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned short>(0U)), 0xABU);
+ EXPECT_EQ(stdc_leading_zeros(0U), 0xACU);
+ EXPECT_EQ(stdc_leading_zeros(0UL), 0xADU);
+ EXPECT_EQ(stdc_leading_zeros(0ULL), 0xAEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroLeadingOnes) {
+ EXPECT_EQ(stdc_leading_ones(static_cast<unsigned char>(0U)), 0xBAU);
+ EXPECT_EQ(stdc_leading_ones(static_cast<unsigned short>(0U)), 0xBBU);
+ EXPECT_EQ(stdc_leading_ones(0U), 0xBCU);
+ EXPECT_EQ(stdc_leading_ones(0UL), 0xBDU);
+ EXPECT_EQ(stdc_leading_ones(0ULL), 0xBEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroTrailingZeros) {
+ EXPECT_EQ(stdc_trailing_zeros(static_cast<unsigned char>(0U)), 0xCAU);
+ EXPECT_EQ(stdc_trailing_zeros(static_cast<unsigned short>(0U)), 0xCBU);
+ EXPECT_EQ(stdc_trailing_zeros(0U), 0xCCU);
+ EXPECT_EQ(stdc_trailing_zeros(0UL), 0xCDU);
+ EXPECT_EQ(stdc_trailing_zeros(0ULL), 0xCEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroTrailingOnes) {
+ EXPECT_EQ(stdc_trailing_ones(static_cast<unsigned char>(0U)), 0xDAU);
+ EXPECT_EQ(stdc_trailing_ones(static_cast<unsigned short>(0U)), 0xDBU);
+ EXPECT_EQ(stdc_trailing_ones(0U), 0xDCU);
+ EXPECT_EQ(stdc_trailing_ones(0UL), 0xDDU);
+ EXPECT_EQ(stdc_trailing_ones(0ULL), 0xDEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroFirstLeadingZero) {
+ EXPECT_EQ(stdc_first_leading_zero(static_cast<unsigned char>(0U)), 0xEAU);
+ EXPECT_EQ(stdc_first_leading_zero(static_cast<unsigned short>(0U)), 0xEBU);
+ EXPECT_EQ(stdc_first_leading_zero(0U), 0xECU);
+ EXPECT_EQ(stdc_first_leading_zero(0UL), 0xEDU);
+ EXPECT_EQ(stdc_first_leading_zero(0ULL), 0xEEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroFirstLeadingOne) {
+ EXPECT_EQ(stdc_first_leading_one(static_cast<unsigned char>(0U)), 0xFAU);
+ EXPECT_EQ(stdc_first_leading_one(static_cast<unsigned short>(0U)), 0xFBU);
+ EXPECT_EQ(stdc_first_leading_one(0U), 0xFCU);
+ EXPECT_EQ(stdc_first_leading_one(0UL), 0xFDU);
+ EXPECT_EQ(stdc_first_leading_one(0ULL), 0xFEU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroFirstTrailingZero) {
+ EXPECT_EQ(stdc_first_trailing_zero(static_cast<unsigned char>(0U)), 0x0AU);
+ EXPECT_EQ(stdc_first_trailing_zero(static_cast<unsigned short>(0U)), 0x0BU);
+ EXPECT_EQ(stdc_first_trailing_zero(0U), 0x0CU);
+ EXPECT_EQ(stdc_first_trailing_zero(0UL), 0x0DU);
+ EXPECT_EQ(stdc_first_trailing_zero(0ULL), 0x0EU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroFirstTrailingOne) {
+ EXPECT_EQ(stdc_first_trailing_one(static_cast<unsigned char>(0U)), 0x1AU);
+ EXPECT_EQ(stdc_first_trailing_one(static_cast<unsigned short>(0U)), 0x1BU);
+ EXPECT_EQ(stdc_first_trailing_one(0U), 0x1CU);
+ EXPECT_EQ(stdc_first_trailing_one(0UL), 0x1DU);
+ EXPECT_EQ(stdc_first_trailing_one(0ULL), 0x1EU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroCountZeros) {
+ EXPECT_EQ(stdc_count_zeros(static_cast<unsigned char>(0U)), 0x2AU);
+ EXPECT_EQ(stdc_count_zeros(static_cast<unsigned short>(0U)), 0x2BU);
+ EXPECT_EQ(stdc_count_zeros(0U), 0x2CU);
+ EXPECT_EQ(stdc_count_zeros(0UL), 0x2DU);
+ EXPECT_EQ(stdc_count_zeros(0ULL), 0x2EU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroCountOnes) {
+ EXPECT_EQ(stdc_count_ones(static_cast<unsigned char>(0U)), 0x3AU);
+ EXPECT_EQ(stdc_count_ones(static_cast<unsigned short>(0U)), 0x3BU);
+ EXPECT_EQ(stdc_count_ones(0U), 0x3CU);
+ EXPECT_EQ(stdc_count_ones(0UL), 0x3DU);
+ EXPECT_EQ(stdc_count_ones(0ULL), 0x3EU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroHasSingleBit) {
+ EXPECT_EQ(stdc_has_single_bit(static_cast<unsigned char>(1U)), false);
+ EXPECT_EQ(stdc_has_single_bit(static_cast<unsigned short>(1U)), false);
+ EXPECT_EQ(stdc_has_single_bit(1U), false);
+ EXPECT_EQ(stdc_has_single_bit(1UL), false);
+ EXPECT_EQ(stdc_has_single_bit(1ULL), false);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroBitWidth) {
+ EXPECT_EQ(stdc_bit_width(static_cast<unsigned char>(1U)), 0x4AU);
+ EXPECT_EQ(stdc_bit_width(static_cast<unsigned short>(1U)), 0x4BU);
+ EXPECT_EQ(stdc_bit_width(1U), 0x4CU);
+ EXPECT_EQ(stdc_bit_width(1UL), 0x4DU);
+ EXPECT_EQ(stdc_bit_width(1ULL), 0x4EU);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroBitFloor) {
+ EXPECT_EQ(stdc_bit_floor(static_cast<unsigned char>(0U)),
+ static_cast<unsigned char>(0x5AU));
+ EXPECT_EQ(stdc_bit_floor(static_cast<unsigned short>(0U)),
+ static_cast<unsigned short>(0x5BU));
+ EXPECT_EQ(stdc_bit_floor(0U), 0x5CU);
+ EXPECT_EQ(stdc_bit_floor(0UL), 0x5DUL);
+ EXPECT_EQ(stdc_bit_floor(0ULL), 0x5EULL);
+}
+
+TEST(LlvmLibcStdbitTest, TypeGenericMacroBitCeil) {
+ EXPECT_EQ(stdc_bit_ceil(static_cast<unsigned char>(0U)),
+ static_cast<unsigned char>(0x6AU));
+ EXPECT_EQ(stdc_bit_ceil(static_cast<unsigned short>(0U)),
+ static_cast<unsigned short>(0x6BU));
+ EXPECT_EQ(stdc_bit_ceil(0U), 0x6CU);
+ EXPECT_EQ(stdc_bit_ceil(0UL), 0x6DUL);
+ EXPECT_EQ(stdc_bit_ceil(0ULL), 0x6EULL);
+}
+
+TEST(LlvmLibcStdbitTest, VersionMacro) {
+ // 7.18.1p2 an integer constant expression with a value equivalent to 202311L.
+ EXPECT_EQ(__STDC_VERSION_STDBIT_H__, 202311L);
+}
+
+TEST(LlvmLibcStdbitTest, EndianMacros) {
+ // 7.18.2p3 The values of the integer constant expressions for
+ // __STDC_ENDIAN_LITTLE__ and __STDC_ENDIAN_BIG__ are not equal.
+ EXPECT_NE(__STDC_ENDIAN_LITTLE__, __STDC_ENDIAN_BIG__);
+ // The standard does allow for __STDC_ENDIAN_NATIVE__ to be an integer
+ // constant expression with an implementation defined value for non-big or
+ // little endianness environments. I assert such machines are no longer
+ // relevant.
+ EXPECT_TRUE(__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_LITTLE__ ||
+ __STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_BIG__);
}
diff --git a/test/include/stdckdint_test.cpp b/test/include/stdckdint_test.cpp
new file mode 100644
index 000000000000..1180a6de9efe
--- /dev/null
+++ b/test/include/stdckdint_test.cpp
@@ -0,0 +1,32 @@
+//===-- Unittests for stdckdint -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "include/llvm-libc-macros/stdckdint-macros.h"
+
+TEST(LlvmLibcStdCkdIntTest, Add) {
+ int result;
+ ASSERT_FALSE(ckd_add(&result, 1, 2));
+ ASSERT_EQ(result, 3);
+ ASSERT_TRUE(ckd_add(&result, INT_MAX, 1));
+}
+
+TEST(LlvmLibcStdCkdIntTest, Sub) {
+ int result;
+ ASSERT_FALSE(ckd_sub(&result, 3, 2));
+ ASSERT_EQ(result, 1);
+ ASSERT_TRUE(ckd_sub(&result, INT_MIN, 1));
+}
+
+TEST(LlvmLibcStdCkdIntTest, Mul) {
+ int result;
+ ASSERT_FALSE(ckd_mul(&result, 2, 3));
+ ASSERT_EQ(result, 6);
+ ASSERT_TRUE(ckd_mul(&result, INT_MAX, 2));
+}
diff --git a/test/include/sys/queue_test.cpp b/test/include/sys/queue_test.cpp
index 48c0e811c615..c10e48d627ca 100644
--- a/test/include/sys/queue_test.cpp
+++ b/test/include/sys/queue_test.cpp
@@ -10,7 +10,7 @@
#include "src/__support/char_vector.h"
#include "test/UnitTest/Test.h"
-#include "llvm-libc-macros/sys-queue-macros.h"
+#include "include/llvm-libc-macros/sys-queue-macros.h"
using LIBC_NAMESPACE::CharVector;
using LIBC_NAMESPACE::cpp::string;
diff --git a/test/integration/src/__support/GPU/scan_reduce.cpp b/test/integration/src/__support/GPU/scan_reduce.cpp
new file mode 100644
index 000000000000..bc621c3300cb
--- /dev/null
+++ b/test/integration/src/__support/GPU/scan_reduce.cpp
@@ -0,0 +1,62 @@
+//===-- Test for the parallel scan and reduction operations on the GPU ----===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/bit.h"
+#include "src/__support/GPU/utils.h"
+#include "test/IntegrationTest/test.h"
+
+using namespace LIBC_NAMESPACE;
+
+static uint32_t sum(uint32_t n) { return n * (n + 1) / 2; }
+
+// Tests a reduction within a convergant warp or wavefront using some known
+// values. For example, if every element in the lane is one, then the sum should
+// be the size of the warp or wavefront, i.e. 1 + 1 + 1 ... + 1.
+static void test_reduce() {
+ uint64_t mask = gpu::get_lane_mask();
+ uint32_t x = gpu::reduce(mask, 1);
+ EXPECT_EQ(x, gpu::get_lane_size());
+
+ uint32_t y = gpu::reduce(mask, gpu::get_lane_id());
+ EXPECT_EQ(y, sum(gpu::get_lane_size() - 1));
+
+ uint32_t z = 0;
+ if (gpu::get_lane_id() % 2)
+ z = gpu::reduce(gpu::get_lane_mask(), 1);
+ gpu::sync_lane(mask);
+
+ EXPECT_EQ(z, gpu::get_lane_id() % 2 ? gpu::get_lane_size() / 2 : 0);
+}
+
+// Tests an accumulation scan within a convergent warp or wavefront using some
+// known values. For example, if every element in the lane is one, then the scan
+// should have each element be equivalent to its ID, i.e. 1, 1 + 1, ...
+static void test_scan() {
+ uint64_t mask = gpu::get_lane_mask();
+
+ uint32_t x = gpu::scan(mask, 1);
+ EXPECT_EQ(x, gpu::get_lane_id() + 1);
+
+ uint32_t y = gpu::scan(mask, gpu::get_lane_id());
+ EXPECT_EQ(y, sum(gpu::get_lane_id()));
+
+ uint32_t z = 0;
+ if (gpu::get_lane_id() % 2)
+ z = gpu::scan(gpu::get_lane_mask(), 1);
+ gpu::sync_lane(mask);
+
+ EXPECT_EQ(z, gpu::get_lane_id() % 2 ? gpu::get_lane_id() / 2 + 1 : 0);
+}
+
+TEST_MAIN(int argc, char **argv, char **envp) {
+ test_reduce();
+
+ test_scan();
+
+ return 0;
+}
diff --git a/test/integration/src/pthread/pthread_create_test.cpp b/test/integration/src/pthread/pthread_create_test.cpp
index 5da91c6ec9a7..29da4d5c3c8d 100644
--- a/test/integration/src/pthread/pthread_create_test.cpp
+++ b/test/integration/src/pthread/pthread_create_test.cpp
@@ -332,7 +332,7 @@ static void run_failure_tests() {
}
TEST_MAIN() {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
run_success_tests();
run_failure_tests();
return 0;
diff --git a/test/integration/src/pthread/pthread_join_test.cpp b/test/integration/src/pthread/pthread_join_test.cpp
index da1a968aa47d..994fa57a6b33 100644
--- a/test/integration/src/pthread/pthread_join_test.cpp
+++ b/test/integration/src/pthread/pthread_join_test.cpp
@@ -25,7 +25,7 @@ static void nullJoinTest() {
}
TEST_MAIN() {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
nullJoinTest();
return 0;
}
diff --git a/test/integration/src/spawn/test_binary_properties.h b/test/integration/src/spawn/test_binary_properties.h
index f1521c218c0c..8e6a1fe6747c 100644
--- a/test/integration/src/spawn/test_binary_properties.h
+++ b/test/integration/src/spawn/test_binary_properties.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
-#define LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
+#ifndef LLVM_LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
+#define LLVM_LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
constexpr int CHILD_FD = 10;
constexpr char TEXT[] = "Hello, posix_spawn";
-#endif // LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
+#endif // LLVM_LIBC_TEST_INTEGRATION_SRC_SPAWN_TEST_BINARY_PROPERTIES_H
diff --git a/test/integration/src/stdio/gpu/printf.cpp b/test/integration/src/stdio/gpu/printf.cpp
new file mode 100644
index 000000000000..97ad4ace1dca
--- /dev/null
+++ b/test/integration/src/stdio/gpu/printf.cpp
@@ -0,0 +1,88 @@
+//===-- RPC test to check args to printf ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "test/IntegrationTest/test.h"
+
+#include "src/__support/GPU/utils.h"
+#include "src/gpu/rpc_fprintf.h"
+#include "src/stdio/fopen.h"
+
+using namespace LIBC_NAMESPACE;
+
+FILE *file = LIBC_NAMESPACE::fopen("testdata/test_data.txt", "w");
+
+TEST_MAIN(int argc, char **argv, char **envp) {
+ ASSERT_TRUE(file && "failed to open file");
+ // Check basic printing.
+ int written = 0;
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "A simple string\n", nullptr, 0);
+ ASSERT_EQ(written, 16);
+
+ const char *str = "A simple string\n";
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%s", &str, sizeof(void *));
+ ASSERT_EQ(written, 16);
+
+ // Check printing a different value with each thread.
+ uint64_t thread_id = gpu::get_thread_id();
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%8ld\n", &thread_id,
+ sizeof(thread_id));
+ ASSERT_EQ(written, 9);
+
+ struct {
+ uint32_t x = 1;
+ char c = 'c';
+ double f = 1.0;
+ } args1;
+ written =
+ LIBC_NAMESPACE::rpc_fprintf(file, "%d%c%.1f\n", &args1, sizeof(args1));
+ ASSERT_EQ(written, 6);
+
+ struct {
+ uint32_t x = 1;
+ const char *str = "A simple string\n";
+ } args2;
+ written =
+ LIBC_NAMESPACE::rpc_fprintf(file, "%032b%s\n", &args2, sizeof(args2));
+ ASSERT_EQ(written, 49);
+
+ // Check that the server correctly handles divergent numbers of arguments.
+ const char *format = gpu::get_thread_id() % 2 ? "%s" : "%20ld\n";
+ written = LIBC_NAMESPACE::rpc_fprintf(file, format, &str, sizeof(void *));
+ ASSERT_EQ(written, gpu::get_thread_id() % 2 ? 16 : 21);
+
+ format = gpu::get_thread_id() % 2 ? "%s" : str;
+ written = LIBC_NAMESPACE::rpc_fprintf(file, format, &str, sizeof(void *));
+ ASSERT_EQ(written, 16);
+
+ // Check that we handle null arguments correctly.
+ struct {
+ void *null = nullptr;
+ } args3;
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%p", &args3, sizeof(args3));
+ ASSERT_EQ(written, 9);
+
+#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%s", &args3, sizeof(args3));
+ ASSERT_EQ(written, 6);
+#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
+
+ // Check for extremely abused variable width arguments
+ struct {
+ uint32_t x = 1;
+ uint32_t y = 2;
+ double f = 1.0;
+ } args4;
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%**d", &args4, sizeof(args4));
+ ASSERT_EQ(written, 4);
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%**d%6d", &args4, sizeof(args4));
+ ASSERT_EQ(written, 10);
+ written = LIBC_NAMESPACE::rpc_fprintf(file, "%**.**f", &args4, sizeof(args4));
+ ASSERT_EQ(written, 7);
+
+ return 0;
+}
diff --git a/test/integration/src/unistd/getcwd_test.cpp b/test/integration/src/unistd/getcwd_test.cpp
index 87687d09b9e7..551768187bf0 100644
--- a/test/integration/src/unistd/getcwd_test.cpp
+++ b/test/integration/src/unistd/getcwd_test.cpp
@@ -31,12 +31,12 @@ TEST_MAIN(int argc, char **argv, char **envp) {
cwd = LIBC_NAMESPACE::getcwd(buffer, 0);
ASSERT_TRUE(cwd == nullptr);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// Insufficient size
cwd = LIBC_NAMESPACE::getcwd(buffer, 2);
ASSERT_TRUE(cwd == nullptr);
- int err = libc_errno;
+ int err = LIBC_NAMESPACE::libc_errno;
ASSERT_EQ(err, ERANGE);
return 0;
diff --git a/test/integration/startup/linux/tls_test.cpp b/test/integration/startup/linux/tls_test.cpp
index 5f235a96006d..2a6385e195a4 100644
--- a/test/integration/startup/linux/tls_test.cpp
+++ b/test/integration/startup/linux/tls_test.cpp
@@ -28,11 +28,11 @@ TEST_MAIN(int argc, char **argv, char **envp) {
// set in errno. Since errno is implemented using a thread
// local var, this helps us test setting of errno and
// reading it back.
- ASSERT_TRUE(libc_errno == 0);
+ ASSERT_ERRNO_SUCCESS();
void *addr = LIBC_NAMESPACE::mmap(nullptr, 0, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
ASSERT_TRUE(addr == MAP_FAILED);
- ASSERT_TRUE(libc_errno == EINVAL);
+ ASSERT_ERRNO_EQ(EINVAL);
return 0;
}
diff --git a/test/src/__support/CPP/array_test.cpp b/test/src/__support/CPP/array_test.cpp
new file mode 100644
index 000000000000..f2d7bff636e4
--- /dev/null
+++ b/test/src/__support/CPP/array_test.cpp
@@ -0,0 +1,66 @@
+//===-- Unittests for Array -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/array.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::cpp::array;
+
+TEST(LlvmLibcArrayTest, Basic) {
+ array<int, 3> a = {0, 1, 2};
+
+ ASSERT_EQ(a.data(), &a.front());
+ ASSERT_EQ(a.front(), 0);
+ ASSERT_EQ(a.back(), 2);
+ ASSERT_EQ(a.size(), size_t{3});
+ ASSERT_EQ(a[1], 1);
+ ASSERT_FALSE(a.empty());
+ ASSERT_NE(a.begin(), a.end());
+ ASSERT_EQ(*a.begin(), a.front());
+
+ auto it = a.rbegin();
+ ASSERT_EQ(*it, 2);
+ ASSERT_EQ(*(++it), 1);
+ ASSERT_EQ(*(++it), 0);
+
+ for (int &x : a)
+ ASSERT_GE(x, 0);
+}
+
+// Test const_iterator and const variant methods.
+TEST(LlvmLibcArrayTest, Const) {
+ const array<int, 3> z = {3, 4, 5};
+
+ ASSERT_EQ(3, z.front());
+ ASSERT_EQ(4, z[1]);
+ ASSERT_EQ(5, z.back());
+ ASSERT_EQ(3, *z.data());
+
+ // begin, cbegin, end, cend
+ array<int, 3>::const_iterator it2 = z.begin();
+ ASSERT_EQ(*it2, z.front());
+ it2 = z.cbegin();
+ ASSERT_EQ(*it2, z.front());
+ it2 = z.end();
+ ASSERT_NE(it2, z.begin());
+ it2 = z.cend();
+ ASSERT_NE(it2, z.begin());
+
+ // rbegin, crbegin, rend, crend
+ array<int, 3>::const_reverse_iterator it = z.rbegin();
+ ASSERT_EQ(*it, z.back());
+ it = z.crbegin();
+ ASSERT_EQ(*it, z.back());
+ it = z.rend();
+ ASSERT_EQ(*--it, z.front());
+ it = z.crend();
+ ASSERT_EQ(*--it, z.front());
+
+ for (const int &x : z)
+ ASSERT_GE(x, 0);
+}
diff --git a/test/src/__support/CPP/bit_test.cpp b/test/src/__support/CPP/bit_test.cpp
index fef551bc1f0e..875b47e6a198 100644
--- a/test/src/__support/CPP/bit_test.cpp
+++ b/test/src/__support/CPP/bit_test.cpp
@@ -8,25 +8,40 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/UInt.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/Test.h"
#include <stdint.h>
namespace LIBC_NAMESPACE::cpp {
-using UnsignedTypes =
- testing::TypeList<unsigned char, unsigned short, unsigned int,
- unsigned long, unsigned long long,
-#if defined(__SIZEOF_INT128__)
- __uint128_t,
-#endif
- cpp::UInt<128>>;
+using UnsignedTypes = testing::TypeList<
+#if defined(LIBC_TYPES_HAS_INT128)
+ __uint128_t,
+#endif // LIBC_TYPES_HAS_INT128
+ unsigned char, unsigned short, unsigned int, unsigned long,
+ unsigned long long, UInt<128>>;
TYPED_TEST(LlvmLibcBitTest, HasSingleBit, UnsignedTypes) {
- EXPECT_FALSE(has_single_bit<T>(T(0)));
- EXPECT_FALSE(has_single_bit<T>(~T(0)));
+ constexpr auto ZERO = T(0);
+ constexpr auto ALL_ONES = T(~ZERO);
+ EXPECT_FALSE(has_single_bit<T>(ZERO));
+ EXPECT_FALSE(has_single_bit<T>(ALL_ONES));
+
for (T value = 1; value; value <<= 1)
EXPECT_TRUE(has_single_bit<T>(value));
+
+ // We test that if two bits are set has_single_bit returns false.
+ // We do this by setting the highest or lowest bit depending or where the
+ // current bit is. This is a bit convoluted but it helps catch a bug on BigInt
+ // where we have to work on an element-by-element basis.
+ constexpr auto MIDPOINT = T(ALL_ONES / 2);
+ constexpr auto LSB = T(1);
+ constexpr auto MSB = T(~(ALL_ONES >> 1));
+ for (T value = 1; value; value <<= 1) {
+ auto two_bits_value = value | ((value <= MIDPOINT) ? MSB : LSB);
+ EXPECT_FALSE(has_single_bit<T>(two_bits_value));
+ }
}
TYPED_TEST(LlvmLibcBitTest, CountLZero, UnsignedTypes) {
@@ -206,4 +221,11 @@ TEST(LlvmLibcBitTest, Rotr) {
rotr<uint64_t>(0x12345678deadbeefULL, -19));
}
+TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypes) {
+ EXPECT_EQ(popcount(T(0)), 0);
+ for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(popcount<T>(cpp::numeric_limits<T>::max() >> i),
+ cpp::numeric_limits<T>::digits - i);
+}
+
} // namespace LIBC_NAMESPACE::cpp
diff --git a/test/src/__support/CPP/limits_test.cpp b/test/src/__support/CPP/limits_test.cpp
index 12641b7b51b6..efcd6839d073 100644
--- a/test/src/__support/CPP/limits_test.cpp
+++ b/test/src/__support/CPP/limits_test.cpp
@@ -8,6 +8,7 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/UInt.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/Test.h"
namespace LIBC_NAMESPACE {
@@ -32,14 +33,13 @@ TEST(LlvmLibcLimitsTest, LimitsFollowSpec) {
}
TEST(LlvmLibcLimitsTest, UInt128Limits) {
- auto umax128 = cpp::numeric_limits<LIBC_NAMESPACE::cpp::UInt<128>>::max();
- auto umax64 =
- LIBC_NAMESPACE::cpp::UInt<128>(cpp::numeric_limits<uint64_t>::max());
+ auto umax128 = cpp::numeric_limits<LIBC_NAMESPACE::UInt<128>>::max();
+ auto umax64 = LIBC_NAMESPACE::UInt<128>(cpp::numeric_limits<uint64_t>::max());
EXPECT_GT(umax128, umax64);
- ASSERT_EQ(~LIBC_NAMESPACE::cpp::UInt<128>(0), umax128);
-#ifdef __SIZEOF_INT128__
+ ASSERT_EQ(~LIBC_NAMESPACE::UInt<128>(0), umax128);
+#ifdef LIBC_TYPES_HAS_INT128
ASSERT_EQ(~__uint128_t(0), cpp::numeric_limits<__uint128_t>::max());
-#endif
+#endif // LIBC_TYPES_HAS_INT128
}
} // namespace LIBC_NAMESPACE
diff --git a/test/src/__support/CPP/stringview_test.cpp b/test/src/__support/CPP/stringview_test.cpp
index 33eb8ab47657..6b68f2a1c47a 100644
--- a/test/src/__support/CPP/stringview_test.cpp
+++ b/test/src/__support/CPP/stringview_test.cpp
@@ -174,3 +174,111 @@ TEST(LlvmLibcStringViewTest, FindLastOf) {
ASSERT_EQ(Empty1.find_last_of('a', 0), string_view::npos);
ASSERT_EQ(Empty1.find_last_of('a', 123), string_view::npos);
}
+
+TEST(LlvmLibcStringViewTest, FindFirstNotOf) {
+ string_view Tmp("abada");
+
+ EXPECT_EQ(Tmp.find_first_not_of('a'), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of('a', 123), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('a', 5), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('a', 4), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('a', 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of('a', 2), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of('a', 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of('a', 0), size_t(1));
+
+ EXPECT_EQ(Tmp.find_first_not_of('b'), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of('b', 123), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('b', 5), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('b', 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of('b', 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of('b', 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of('b', 1), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of('b', 0), size_t(0));
+
+ EXPECT_EQ(Tmp.find_first_not_of('d'), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of('d', 123), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('d', 5), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('d', 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of('d', 3), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of('d', 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of('d', 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of('d', 0), size_t(0));
+
+ EXPECT_EQ(Tmp.find_first_not_of('e'), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of('e', 123), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('e', 5), string_view::npos);
+ EXPECT_EQ(Tmp.find_first_not_of('e', 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of('e', 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of('e', 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of('e', 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of('e', 0), size_t(0));
+
+ string_view Empty;
+ EXPECT_EQ(Empty.find_first_not_of('a'), string_view::npos);
+ EXPECT_EQ(Empty.find_first_not_of('a', 0), string_view::npos);
+ EXPECT_EQ(Empty.find_first_not_of('a', 123), string_view::npos);
+
+ string_view Empty1("");
+ EXPECT_EQ(Empty1.find_first_not_of('a'), string_view::npos);
+ EXPECT_EQ(Empty1.find_first_not_of('a', 0), string_view::npos);
+ EXPECT_EQ(Empty1.find_first_not_of('a', 123), string_view::npos);
+
+ string_view Full("aaaaaaa");
+ EXPECT_EQ(Full.find_first_not_of('a'), string_view::npos);
+ EXPECT_EQ(Full.find_first_not_of('a', 0), string_view::npos);
+ EXPECT_EQ(Full.find_first_not_of('a', 123), string_view::npos);
+
+ EXPECT_EQ(Full.find_first_not_of('b'), size_t(0));
+ EXPECT_EQ(Full.find_first_not_of('b', 0), size_t(0));
+ EXPECT_EQ(Full.find_first_not_of('b', 123), string_view::npos);
+}
+
+TEST(LlvmLibcStringViewTest, Contains) {
+ string_view Empty;
+ for (char c = 'a'; c < 'z'; ++c)
+ EXPECT_FALSE(Empty.contains(c));
+
+ string_view Tmp("abada");
+ EXPECT_TRUE(Tmp.contains('a'));
+ EXPECT_TRUE(Tmp.contains('b'));
+ EXPECT_FALSE(Tmp.contains('c'));
+ EXPECT_TRUE(Tmp.contains('d'));
+ EXPECT_FALSE(Tmp.contains('e'));
+
+ EXPECT_TRUE(Tmp.substr(1).contains('a'));
+ EXPECT_TRUE(Tmp.substr(1).contains('b'));
+ EXPECT_FALSE(Tmp.substr(1).contains('c'));
+ EXPECT_TRUE(Tmp.substr(1).contains('d'));
+ EXPECT_FALSE(Tmp.substr(1).contains('e'));
+
+ EXPECT_TRUE(Tmp.substr(2).contains('a'));
+ EXPECT_FALSE(Tmp.substr(2).contains('b'));
+ EXPECT_FALSE(Tmp.substr(2).contains('c'));
+ EXPECT_TRUE(Tmp.substr(2).contains('d'));
+ EXPECT_FALSE(Tmp.substr(2).contains('e'));
+
+ EXPECT_TRUE(Tmp.substr(3).contains('a'));
+ EXPECT_FALSE(Tmp.substr(3).contains('b'));
+ EXPECT_FALSE(Tmp.substr(3).contains('c'));
+ EXPECT_TRUE(Tmp.substr(3).contains('d'));
+ EXPECT_FALSE(Tmp.substr(3).contains('e'));
+
+ EXPECT_TRUE(Tmp.substr(4).contains('a'));
+ EXPECT_FALSE(Tmp.substr(4).contains('b'));
+ EXPECT_FALSE(Tmp.substr(4).contains('c'));
+ EXPECT_FALSE(Tmp.substr(4).contains('d'));
+ EXPECT_FALSE(Tmp.substr(4).contains('e'));
+
+ EXPECT_FALSE(Tmp.substr(5).contains('a'));
+ EXPECT_FALSE(Tmp.substr(5).contains('b'));
+ EXPECT_FALSE(Tmp.substr(5).contains('c'));
+ EXPECT_FALSE(Tmp.substr(5).contains('d'));
+ EXPECT_FALSE(Tmp.substr(5).contains('e'));
+
+ EXPECT_FALSE(Tmp.substr(6).contains('a'));
+ EXPECT_FALSE(Tmp.substr(6).contains('b'));
+ EXPECT_FALSE(Tmp.substr(6).contains('c'));
+ EXPECT_FALSE(Tmp.substr(6).contains('d'));
+ EXPECT_FALSE(Tmp.substr(6).contains('e'));
+}
diff --git a/test/src/__support/FPUtil/dyadic_float_test.cpp b/test/src/__support/FPUtil/dyadic_float_test.cpp
index a9f9842c5030..5ee9aaad5638 100644
--- a/test/src/__support/FPUtil/dyadic_float_test.cpp
+++ b/test/src/__support/FPUtil/dyadic_float_test.cpp
@@ -15,7 +15,6 @@
using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>;
using Float192 = LIBC_NAMESPACE::fputil::DyadicFloat<192>;
using Float256 = LIBC_NAMESPACE::fputil::DyadicFloat<256>;
-using Sign = LIBC_NAMESPACE::fputil::Sign;
TEST(LlvmLibcDyadicFloatTest, BasicConversions) {
Float128 x(Sign::POS, /*exponent*/ 0,
@@ -56,3 +55,37 @@ TEST(LlvmLibcDyadicFloatTest, QuickMul) {
Float256 z = quick_mul(x, y);
EXPECT_FP_EQ_ALL_ROUNDING(double(x) * double(y), double(z));
}
+
+#define TEST_EDGE_RANGES(Name, Type) \
+ TEST(LlvmLibcDyadicFloatTest, EdgeRanges##Name) { \
+ using Bits = LIBC_NAMESPACE::fputil::FPBits<Type>; \
+ using DFType = LIBC_NAMESPACE::fputil::DyadicFloat<Bits::STORAGE_LEN>; \
+ Type max_normal = Bits::max_normal().get_val(); \
+ Type min_normal = Bits::min_normal().get_val(); \
+ Type min_subnormal = Bits::min_subnormal().get_val(); \
+ Type two(2); \
+ \
+ DFType x(min_normal); \
+ EXPECT_FP_EQ_ALL_ROUNDING(min_normal, static_cast<Type>(x)); \
+ --x.exponent; \
+ EXPECT_FP_EQ(min_normal / two, static_cast<Type>(x)); \
+ \
+ DFType y(two *min_normal - min_subnormal); \
+ --y.exponent; \
+ EXPECT_FP_EQ(min_normal, static_cast<Type>(y)); \
+ \
+ DFType z(min_subnormal); \
+ EXPECT_FP_EQ_ALL_ROUNDING(min_subnormal, static_cast<Type>(z)); \
+ --z.exponent; \
+ EXPECT_FP_EQ(Bits::zero().get_val(), static_cast<Type>(z)); \
+ \
+ DFType t(max_normal); \
+ EXPECT_FP_EQ_ALL_ROUNDING(max_normal, static_cast<Type>(t)); \
+ ++t.exponent; \
+ EXPECT_FP_EQ(Bits::inf().get_val(), static_cast<Type>(t)); \
+ } \
+ static_assert(true, "Require semicolon.")
+
+TEST_EDGE_RANGES(Float, float);
+TEST_EDGE_RANGES(Double, double);
+TEST_EDGE_RANGES(LongDouble, long double);
diff --git a/test/src/__support/FPUtil/fpbits_test.cpp b/test/src/__support/FPUtil/fpbits_test.cpp
index 17737af9ce14..af20b1a0bdc7 100644
--- a/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/test/src/__support/FPUtil/fpbits_test.cpp
@@ -1,4 +1,4 @@
-//===-- Unittests for the DyadicFloat class -------------------------------===//
+//===-- Unittests for the FPBits class ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,44 +8,50 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/fpbits_str.h"
+#include "src/__support/integer_literals.h"
+#include "src/__support/sign.h" // Sign
#include "test/UnitTest/Test.h"
using LIBC_NAMESPACE::fputil::FPBits;
using LIBC_NAMESPACE::fputil::FPType;
-using LIBC_NAMESPACE::fputil::Sign;
using LIBC_NAMESPACE::fputil::internal::FPRep;
+using LIBC_NAMESPACE::operator""_u16;
+using LIBC_NAMESPACE::operator""_u32;
+using LIBC_NAMESPACE::operator""_u64;
+using LIBC_NAMESPACE::operator""_u128;
+
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
using Rep = FPRep<FPType::IEEE754_Binary16>;
using u16 = typename Rep::StorageType;
- EXPECT_EQ(u16(0b0'00000'0000000000), u16(Rep::zero()));
- EXPECT_EQ(u16(0b0'01111'0000000000), u16(Rep::one()));
- EXPECT_EQ(u16(0b0'00000'0000000001), u16(Rep::min_subnormal()));
- EXPECT_EQ(u16(0b0'00000'1111111111), u16(Rep::max_subnormal()));
- EXPECT_EQ(u16(0b0'00001'0000000000), u16(Rep::min_normal()));
- EXPECT_EQ(u16(0b0'11110'1111111111), u16(Rep::max_normal()));
- EXPECT_EQ(u16(0b0'11111'0000000000), u16(Rep::inf()));
- EXPECT_EQ(u16(0b0'11111'0100000000), u16(Rep::signaling_nan()));
- EXPECT_EQ(u16(0b0'11111'1000000000), u16(Rep::quiet_nan()));
+ EXPECT_EQ(0b0'00000'0000000000_u16, u16(Rep::zero()));
+ EXPECT_EQ(0b0'01111'0000000000_u16, u16(Rep::one()));
+ EXPECT_EQ(0b0'00000'0000000001_u16, u16(Rep::min_subnormal()));
+ EXPECT_EQ(0b0'00000'1111111111_u16, u16(Rep::max_subnormal()));
+ EXPECT_EQ(0b0'00001'0000000000_u16, u16(Rep::min_normal()));
+ EXPECT_EQ(0b0'11110'1111111111_u16, u16(Rep::max_normal()));
+ EXPECT_EQ(0b0'11111'0000000000_u16, u16(Rep::inf()));
+ EXPECT_EQ(0b0'11111'0100000000_u16, u16(Rep::signaling_nan()));
+ EXPECT_EQ(0b0'11111'1000000000_u16, u16(Rep::quiet_nan()));
}
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
using Rep = FPRep<FPType::IEEE754_Binary32>;
using u32 = typename Rep::StorageType;
- EXPECT_EQ(u32(0b0'00000000'00000000000000000000000), u32(Rep::zero()));
- EXPECT_EQ(u32(0b0'01111111'00000000000000000000000), u32(Rep::one()));
- EXPECT_EQ(u32(0b0'00000000'00000000000000000000001),
+ EXPECT_EQ(0b0'00000000'00000000000000000000000_u32, u32(Rep::zero()));
+ EXPECT_EQ(0b0'01111111'00000000000000000000000_u32, u32(Rep::one()));
+ EXPECT_EQ(0b0'00000000'00000000000000000000001_u32,
u32(Rep::min_subnormal()));
- EXPECT_EQ(u32(0b0'00000000'11111111111111111111111),
+ EXPECT_EQ(0b0'00000000'11111111111111111111111_u32,
u32(Rep::max_subnormal()));
- EXPECT_EQ(u32(0b0'00000001'00000000000000000000000), u32(Rep::min_normal()));
- EXPECT_EQ(u32(0b0'11111110'11111111111111111111111), u32(Rep::max_normal()));
- EXPECT_EQ(u32(0b0'11111111'00000000000000000000000), u32(Rep::inf()));
- EXPECT_EQ(u32(0b0'11111111'01000000000000000000000),
+ EXPECT_EQ(0b0'00000001'00000000000000000000000_u32, u32(Rep::min_normal()));
+ EXPECT_EQ(0b0'11111110'11111111111111111111111_u32, u32(Rep::max_normal()));
+ EXPECT_EQ(0b0'11111111'00000000000000000000000_u32, u32(Rep::inf()));
+ EXPECT_EQ(0b0'11111111'01000000000000000000000_u32,
u32(Rep::signaling_nan()));
- EXPECT_EQ(u32(0b0'11111111'10000000000000000000000), u32(Rep::quiet_nan()));
+ EXPECT_EQ(0b0'11111111'10000000000000000000000_u32, u32(Rep::quiet_nan()));
}
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
@@ -53,80 +59,63 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
using u64 = typename Rep::StorageType;
EXPECT_EQ(
- u64(0b0'00000000000'0000000000000000000000000000000000000000000000000000),
+ 0b0'00000000000'0000000000000000000000000000000000000000000000000000_u64,
u64(Rep::zero()));
EXPECT_EQ(
- u64(0b0'01111111111'0000000000000000000000000000000000000000000000000000),
+ 0b0'01111111111'0000000000000000000000000000000000000000000000000000_u64,
u64(Rep::one()));
EXPECT_EQ(
- u64(0b0'00000000000'0000000000000000000000000000000000000000000000000001),
+ 0b0'00000000000'0000000000000000000000000000000000000000000000000001_u64,
u64(Rep::min_subnormal()));
EXPECT_EQ(
- u64(0b0'00000000000'1111111111111111111111111111111111111111111111111111),
+ 0b0'00000000000'1111111111111111111111111111111111111111111111111111_u64,
u64(Rep::max_subnormal()));
EXPECT_EQ(
- u64(0b0'00000000001'0000000000000000000000000000000000000000000000000000),
+ 0b0'00000000001'0000000000000000000000000000000000000000000000000000_u64,
u64(Rep::min_normal()));
EXPECT_EQ(
- u64(0b0'11111111110'1111111111111111111111111111111111111111111111111111),
+ 0b0'11111111110'1111111111111111111111111111111111111111111111111111_u64,
u64(Rep::max_normal()));
EXPECT_EQ(
- u64(0b0'11111111111'0000000000000000000000000000000000000000000000000000),
+ 0b0'11111111111'0000000000000000000000000000000000000000000000000000_u64,
u64(Rep::inf()));
EXPECT_EQ(
- u64(0b0'11111111111'0100000000000000000000000000000000000000000000000000),
+ 0b0'11111111111'0100000000000000000000000000000000000000000000000000_u64,
u64(Rep::signaling_nan()));
EXPECT_EQ(
- u64(0b0'11111111111'1000000000000000000000000000000000000000000000000000),
+ 0b0'11111111111'1000000000000000000000000000000000000000000000000000_u64,
u64(Rep::quiet_nan()));
}
-static constexpr UInt128 u128(uint64_t hi, uint64_t lo) {
-#if defined(__SIZEOF_INT128__)
- return __uint128_t(hi) << 64 | __uint128_t(lo);
-#else
- return UInt128({lo, hi});
-#endif
-}
-
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
using Rep = FPRep<FPType::IEEE754_Binary128>;
EXPECT_EQ(
- u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::zero()));
EXPECT_EQ(
- u128(0b0'011111111111111'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'011111111111111'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::one()));
EXPECT_EQ(
- u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000001),
+ 0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001_u128,
UInt128(Rep::min_subnormal()));
EXPECT_EQ(
- u128(0b0'000000000000000'111111111111111111111111111111111111111111111111,
- 0b1111111111111111111111111111111111111111111111111111111111111111),
+ 0b0'000000000000000'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111_u128,
UInt128(Rep::max_subnormal()));
EXPECT_EQ(
- u128(0b0'000000000000001'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'000000000000001'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::min_normal()));
EXPECT_EQ(
- u128(0b0'111111111111110'111111111111111111111111111111111111111111111111,
- 0b1111111111111111111111111111111111111111111111111111111111111111),
+ 0b0'111111111111110'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111_u128,
UInt128(Rep::max_normal()));
EXPECT_EQ(
- u128(0b0'111111111111111'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::inf()));
EXPECT_EQ(
- u128(0b0'111111111111111'010000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'111111111111111'0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::signaling_nan()));
EXPECT_EQ(
- u128(0b0'111111111111111'100000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::quiet_nan()));
}
@@ -134,89 +123,73 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
using Rep = FPRep<FPType::X86_Binary80>;
EXPECT_EQ(
- u128(0b0'000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'0000000000000000000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::zero()));
EXPECT_EQ(
- u128(0b0'011111111111111,
- 0b1000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'0111111111111111000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::one()));
EXPECT_EQ(
- u128(0b0'000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000001),
+ 0b0'0000000000000000000000000000000000000000000000000000000000000000000000000000001_u128,
UInt128(Rep::min_subnormal()));
EXPECT_EQ(
- u128(0b0'000000000000000,
- 0b0111111111111111111111111111111111111111111111111111111111111111),
+ 0b0'0000000000000000111111111111111111111111111111111111111111111111111111111111111_u128,
UInt128(Rep::max_subnormal()));
EXPECT_EQ(
- u128(0b0'000000000000001,
- 0b1000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'0000000000000011000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::min_normal()));
EXPECT_EQ(
- u128(0b0'111111111111110,
- 0b1111111111111111111111111111111111111111111111111111111111111111),
+ 0b0'1111111111111101111111111111111111111111111111111111111111111111111111111111111_u128,
UInt128(Rep::max_normal()));
EXPECT_EQ(
- u128(0b0'111111111111111,
- 0b1000000000000000000000000000000000000000000000000000000000000000),
+ 0b0'1111111111111111000000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::inf()));
EXPECT_EQ(
- u128(0b0'111111111111111,
- 0b1010000000000000000000000000000000000000000000000000000000000000),
+ 0b0'1111111111111111010000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::signaling_nan()));
EXPECT_EQ(
- u128(0b0'111111111111111,
- 0b1100000000000000000000000000000000000000000000000000000000000000),
+ 0b0'1111111111111111100000000000000000000000000000000000000000000000000000000000000_u128,
UInt128(Rep::quiet_nan()));
}
TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
using Rep = FPRep<FPType::X86_Binary80>;
- const auto is_nan = [](uint64_t hi, uint64_t lo) {
- Rep rep;
- rep.set_uintval(u128(hi, lo));
- return rep.is_nan();
- };
-
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Pseudo-Infinity
- 0b0000000000000000000000000000000000000000000000000000000000000000));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Pseudo Not a Number
- 0b0000000000000000000000000000000000000000000000000000000000000001));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Pseudo Not a Number
- 0b0100000000000000000000000000000000000000000000000000000000000000));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Signalling Not a Number
- 0b1000000000000000000000000000000000000000000000000000000000000001));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Floating-point Indefinite
- 0b1100000000000000000000000000000000000000000000000000000000000000));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111111, // NAN : Quiet Not a Number
- 0b1100000000000000000000000000000000000000000000000000000000000001));
- EXPECT_TRUE(is_nan(
- 0b0'111111111111110, // NAN : Unnormal
- 0b0000000000000000000000000000000000000000000000000000000000000000));
-
- EXPECT_FALSE(is_nan(
- 0b0'000000000000000, // Zero
- 0b0000000000000000000000000000000000000000000000000000000000000000));
- EXPECT_FALSE(is_nan(
- 0b0'000000000000000, // Subnormal
- 0b0000000000000000000000000000000000000000000000000000000000000001));
- EXPECT_FALSE(is_nan(
- 0b0'000000000000000, // Pseudo Denormal
- 0b1000000000000000000000000000000000000000000000000000000000000001));
- EXPECT_FALSE(is_nan(
- 0b0'111111111111111, // Infinity
- 0b1000000000000000000000000000000000000000000000000000000000000000));
- EXPECT_FALSE(is_nan(
- 0b0'111111111111110, // Normalized
- 0b1000000000000000000000000000000000000000000000000000000000000000));
+ EXPECT_TRUE( // NAN : Pseudo-Infinity
+ Rep(0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Pseudo Not a Number
+ Rep(0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000001_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Pseudo Not a Number
+ Rep(0b0'111111111111111'0100000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Signalling Not a Number
+ Rep(0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000001_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Floating-point Indefinite
+ Rep(0b0'111111111111111'1100000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Quiet Not a Number
+ Rep(0b0'111111111111111'1100000000000000000000000000000000000000000000000000000000000001_u128)
+ .is_nan());
+ EXPECT_TRUE( // NAN : Unnormal
+ Rep(0b0'111111111111110'0000000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_FALSE( // Zero
+ Rep(0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_FALSE( // Subnormal
+ Rep(0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000001_u128)
+ .is_nan());
+ EXPECT_FALSE( // Pseudo Denormal
+ Rep(0b0'000000000000000'1000000000000000000000000000000000000000000000000000000000000001_u128)
+ .is_nan());
+ EXPECT_FALSE( // Infinity
+ Rep(0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
+ EXPECT_FALSE( // Normalized
+ Rep(0b0'111111111111110'1000000000000000000000000000000000000000000000000000000000000000_u128)
+ .is_nan());
}
enum class FP {
@@ -231,47 +204,47 @@ enum class FP {
QUIET_NAN
};
+constexpr FP all_fp_values[] = {
+ FP::ZERO, FP::MIN_SUBNORMAL, FP::MAX_SUBNORMAL,
+ FP::MIN_NORMAL, FP::ONE, FP::MAX_NORMAL,
+ FP::INF, FP::SIGNALING_NAN, FP::QUIET_NAN,
+};
+
+constexpr Sign all_signs[] = {Sign::POS, Sign::NEG};
+
using FPTypes = LIBC_NAMESPACE::testing::TypeList<
FPRep<FPType::IEEE754_Binary16>, FPRep<FPType::IEEE754_Binary32>,
FPRep<FPType::IEEE754_Binary64>, FPRep<FPType::IEEE754_Binary128>,
FPRep<FPType::X86_Binary80>>;
+template <typename T> constexpr auto make(Sign sign, FP fp) {
+ switch (fp) {
+ case FP::ZERO:
+ return T::zero(sign);
+ case FP::MIN_SUBNORMAL:
+ return T::min_subnormal(sign);
+ case FP::MAX_SUBNORMAL:
+ return T::max_subnormal(sign);
+ case FP::MIN_NORMAL:
+ return T::min_normal(sign);
+ case FP::ONE:
+ return T::one(sign);
+ case FP::MAX_NORMAL:
+ return T::max_normal(sign);
+ case FP::INF:
+ return T::inf(sign);
+ case FP::SIGNALING_NAN:
+ return T::signaling_nan(sign);
+ case FP::QUIET_NAN:
+ return T::quiet_nan(sign);
+ }
+}
+
// Tests all properties for all types of float.
TYPED_TEST(LlvmLibcFPBitsTest, Properties, FPTypes) {
- static constexpr auto make_storage = [](Sign sign, FP fp) {
- switch (fp) {
- case FP::ZERO:
- return T::zero(sign);
- case FP::MIN_SUBNORMAL:
- return T::min_subnormal(sign);
- case FP::MAX_SUBNORMAL:
- return T::max_subnormal(sign);
- case FP::MIN_NORMAL:
- return T::min_normal(sign);
- case FP::ONE:
- return T::one(sign);
- case FP::MAX_NORMAL:
- return T::max_normal(sign);
- case FP::INF:
- return T::inf(sign);
- case FP::SIGNALING_NAN:
- return T::signaling_nan(sign);
- case FP::QUIET_NAN:
- return T::quiet_nan(sign);
- }
- };
- static constexpr auto make = [](Sign sign, FP fp) -> T {
- return T(make_storage(sign, fp));
- };
- constexpr FP fp_values[] = {
- FP::ZERO, FP::MIN_SUBNORMAL, FP::MAX_SUBNORMAL,
- FP::MIN_NORMAL, FP::ONE, FP::MAX_NORMAL,
- FP::INF, FP::SIGNALING_NAN, FP::QUIET_NAN,
- };
- constexpr Sign signs[] = {Sign::POS, Sign::NEG};
- for (Sign sign : signs) {
- for (FP fp : fp_values) {
- const T value = make(sign, fp);
+ for (Sign sign : all_signs) {
+ for (FP fp : all_fp_values) {
+ const T value = make<T>(sign, fp);
// is_zero
ASSERT_EQ(value.is_zero(), fp == FP::ZERO);
// is_inf_or_nan
@@ -306,6 +279,27 @@ TYPED_TEST(LlvmLibcFPBitsTest, Properties, FPTypes) {
}
}
+#define ASSERT_SAME_REP(A, B) ASSERT_EQ(A.uintval(), B.uintval());
+
+TYPED_TEST(LlvmLibcFPBitsTest, NextTowardInf, FPTypes) {
+ struct {
+ FP before, after;
+ } TEST_CASES[] = {
+ {FP::ZERO, FP::MIN_SUBNORMAL}, //
+ {FP::MAX_SUBNORMAL, FP::MIN_NORMAL}, //
+ {FP::MAX_NORMAL, FP::INF}, //
+ {FP::INF, FP::INF}, //
+ {FP::QUIET_NAN, FP::QUIET_NAN}, //
+ {FP::SIGNALING_NAN, FP::SIGNALING_NAN}, //
+ };
+ for (Sign sign : all_signs) {
+ for (auto tc : TEST_CASES) {
+ T val = make<T>(sign, tc.before);
+ ASSERT_SAME_REP(val.next_toward_inf(), make<T>(sign, tc.after));
+ }
+ }
+}
+
TEST(LlvmLibcFPBitsTest, FloatType) {
using FloatBits = FPBits<float>;
@@ -318,49 +312,49 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
FloatBits zero(0.0f);
EXPECT_TRUE(zero.is_pos());
- EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0));
- EXPECT_EQ(zero.get_mantissa(), static_cast<uint32_t>(0));
- EXPECT_EQ(zero.uintval(), static_cast<uint32_t>(0x00000000));
+ EXPECT_EQ(zero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(zero.get_mantissa(), 0_u32);
+ EXPECT_EQ(zero.uintval(), 0_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(),
"0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)");
FloatBits negzero(-0.0f);
EXPECT_TRUE(negzero.is_neg());
- EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0));
- EXPECT_EQ(negzero.get_mantissa(), static_cast<uint32_t>(0));
- EXPECT_EQ(negzero.uintval(), static_cast<uint32_t>(0x80000000));
+ EXPECT_EQ(negzero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(negzero.get_mantissa(), 0_u32);
+ EXPECT_EQ(negzero.uintval(), 0x80000000_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(),
"0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)");
FloatBits one(1.0f);
EXPECT_TRUE(one.is_pos());
- EXPECT_EQ(one.get_biased_exponent(), static_cast<uint16_t>(0x7F));
- EXPECT_EQ(one.get_mantissa(), static_cast<uint32_t>(0));
- EXPECT_EQ(one.uintval(), static_cast<uint32_t>(0x3F800000));
+ EXPECT_EQ(one.get_biased_exponent(), 0x7F_u16);
+ EXPECT_EQ(one.get_mantissa(), 0_u32);
+ EXPECT_EQ(one.uintval(), 0x3F800000_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(),
"0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)");
FloatBits negone(-1.0f);
EXPECT_TRUE(negone.is_neg());
- EXPECT_EQ(negone.get_biased_exponent(), static_cast<uint16_t>(0x7F));
- EXPECT_EQ(negone.get_mantissa(), static_cast<uint32_t>(0));
- EXPECT_EQ(negone.uintval(), static_cast<uint32_t>(0xBF800000));
+ EXPECT_EQ(negone.get_biased_exponent(), 0x7F_u16);
+ EXPECT_EQ(negone.get_mantissa(), 0_u32);
+ EXPECT_EQ(negone.uintval(), 0xBF800000_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(),
"0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)");
FloatBits num(1.125f);
EXPECT_TRUE(num.is_pos());
- EXPECT_EQ(num.get_biased_exponent(), static_cast<uint16_t>(0x7F));
- EXPECT_EQ(num.get_mantissa(), static_cast<uint32_t>(0x00100000));
- EXPECT_EQ(num.uintval(), static_cast<uint32_t>(0x3F900000));
+ EXPECT_EQ(num.get_biased_exponent(), 0x7F_u16);
+ EXPECT_EQ(num.get_mantissa(), 0x00100000_u32);
+ EXPECT_EQ(num.uintval(), 0x3F900000_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(),
"0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)");
FloatBits negnum(-1.125f);
EXPECT_TRUE(negnum.is_neg());
- EXPECT_EQ(negnum.get_biased_exponent(), static_cast<uint16_t>(0x7F));
- EXPECT_EQ(negnum.get_mantissa(), static_cast<uint32_t>(0x00100000));
- EXPECT_EQ(negnum.uintval(), static_cast<uint32_t>(0xBF900000));
+ EXPECT_EQ(negnum.get_biased_exponent(), 0x7F_u16);
+ EXPECT_EQ(negnum.get_mantissa(), 0x00100000_u32);
+ EXPECT_EQ(negnum.uintval(), 0xBF900000_u32);
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)");
@@ -380,49 +374,49 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
DoubleBits zero(0.0);
EXPECT_TRUE(zero.is_pos());
- EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(zero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
- EXPECT_EQ(zero.uintval(), static_cast<uint64_t>(0x0000000000000000));
+ EXPECT_EQ(zero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(zero.get_mantissa(), 0_u64);
+ EXPECT_EQ(zero.uintval(), 0_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(),
"0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)");
DoubleBits negzero(-0.0);
EXPECT_TRUE(negzero.is_neg());
- EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(negzero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
- EXPECT_EQ(negzero.uintval(), static_cast<uint64_t>(0x8000000000000000));
+ EXPECT_EQ(negzero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(negzero.get_mantissa(), 0_u64);
+ EXPECT_EQ(negzero.uintval(), 0x8000000000000000_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(),
"0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)");
DoubleBits one(1.0);
EXPECT_TRUE(one.is_pos());
- EXPECT_EQ(one.get_biased_exponent(), static_cast<uint16_t>(0x03FF));
- EXPECT_EQ(one.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
- EXPECT_EQ(one.uintval(), static_cast<uint64_t>(0x3FF0000000000000));
+ EXPECT_EQ(one.get_biased_exponent(), 0x03FF_u16);
+ EXPECT_EQ(one.get_mantissa(), 0_u64);
+ EXPECT_EQ(one.uintval(), 0x3FF0000000000000_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(),
"0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)");
DoubleBits negone(-1.0);
EXPECT_TRUE(negone.is_neg());
- EXPECT_EQ(negone.get_biased_exponent(), static_cast<uint16_t>(0x03FF));
- EXPECT_EQ(negone.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
- EXPECT_EQ(negone.uintval(), static_cast<uint64_t>(0xBFF0000000000000));
+ EXPECT_EQ(negone.get_biased_exponent(), 0x03FF_u16);
+ EXPECT_EQ(negone.get_mantissa(), 0_u64);
+ EXPECT_EQ(negone.uintval(), 0xBFF0000000000000_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(),
"0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)");
DoubleBits num(1.125);
EXPECT_TRUE(num.is_pos());
- EXPECT_EQ(num.get_biased_exponent(), static_cast<uint16_t>(0x03FF));
- EXPECT_EQ(num.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
- EXPECT_EQ(num.uintval(), static_cast<uint64_t>(0x3FF2000000000000));
+ EXPECT_EQ(num.get_biased_exponent(), 0x03FF_u16);
+ EXPECT_EQ(num.get_mantissa(), 0x0002000000000000_u64);
+ EXPECT_EQ(num.uintval(), 0x3FF2000000000000_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(),
"0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)");
DoubleBits negnum(-1.125);
EXPECT_TRUE(negnum.is_neg());
- EXPECT_EQ(negnum.get_biased_exponent(), static_cast<uint16_t>(0x03FF));
- EXPECT_EQ(negnum.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
- EXPECT_EQ(negnum.uintval(), static_cast<uint64_t>(0xBFF2000000000000));
+ EXPECT_EQ(negnum.get_biased_exponent(), 0x03FF_u16);
+ EXPECT_EQ(negnum.get_mantissa(), 0x0002000000000000_u64);
+ EXPECT_EQ(negnum.uintval(), 0xBFF2000000000000_u64);
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)");
@@ -446,10 +440,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits zero(0.0l);
EXPECT_TRUE(zero.is_pos());
- EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_EQ(zero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(zero.get_mantissa(), 0_u128);
+ EXPECT_EQ(zero.uintval(), 0_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(zero).c_str(),
"0x00000000000000000000000000000000 = "
@@ -457,10 +450,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits negzero(-0.0l);
EXPECT_TRUE(negzero.is_neg());
- EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 79);
+ EXPECT_EQ(negzero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(negzero.get_mantissa(), 0_u128);
+ EXPECT_EQ(negzero.uintval(), 0x8000'00000000'00000000_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(negzero).c_str(),
"0x00000000000080000000000000000000 = "
@@ -468,9 +460,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits one(1.0l);
EXPECT_TRUE(one.is_pos());
- EXPECT_EQ(one.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
- EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF8) << 60);
+ EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(one.get_mantissa(), 0_u128);
+ EXPECT_EQ(one.uintval(), 0x3FFF'80000000'00000000_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(one).c_str(),
"0x0000000000003FFF8000000000000000 = "
@@ -478,10 +470,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits negone(-1.0l);
EXPECT_TRUE(negone.is_neg());
- EXPECT_EQ(negone.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF8) << 60);
+ EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negone.get_mantissa(), 0_u128);
+ EXPECT_EQ(negone.uintval(), 0xBFFF'80000000'00000000_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(negone).c_str(),
"0x000000000000BFFF8000000000000000 = "
@@ -489,9 +480,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits num(1.125l);
EXPECT_TRUE(num.is_pos());
- EXPECT_EQ(num.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x1) << 60);
- EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF9) << 60);
+ EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(num.get_mantissa(), 0x10000000'00000000_u128);
+ EXPECT_EQ(num.uintval(), 0x3FFF'90000000'00000000_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(num).c_str(),
"0x0000000000003FFF9000000000000000 = "
@@ -499,9 +490,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LongDoubleBits negnum(-1.125l);
EXPECT_TRUE(negnum.is_neg());
- EXPECT_EQ(negnum.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x1) << 60);
- EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF9) << 60);
+ EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negnum.get_mantissa(), 0x10000000'00000000_u128);
+ EXPECT_EQ(negnum.uintval(), 0xBFFF'90000000'00000000_u128);
EXPECT_STREQ(
LIBC_NAMESPACE::str(negnum).c_str(),
"0x000000000000BFFF9000000000000000 = "
@@ -512,7 +503,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
}
#else
TEST(LlvmLibcFPBitsTest, LongDoubleType) {
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
return; // The tests for the "double" type cover for this case.
#else
using LongDoubleBits = FPBits<long double>;
@@ -526,57 +517,54 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
LongDoubleBits zero(0.0l);
EXPECT_TRUE(zero.is_pos());
- EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_EQ(zero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(zero.get_mantissa(), 0_u128);
+ EXPECT_EQ(zero.uintval(), 0_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(),
"0x00000000000000000000000000000000 = "
"(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
LongDoubleBits negzero(-0.0l);
EXPECT_TRUE(negzero.is_neg());
- EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 127);
+ EXPECT_EQ(negzero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(negzero.get_mantissa(), 0_u128);
+ EXPECT_EQ(negzero.uintval(), 0x80000000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(),
"0x80000000000000000000000000000000 = "
"(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)");
LongDoubleBits one(1.0l);
EXPECT_TRUE(one.is_pos());
- EXPECT_EQ(one.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
- EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
+ EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(one.get_mantissa(), 0_u128);
+ EXPECT_EQ(one.uintval(), 0x3FFF0000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(),
"0x3FFF0000000000000000000000000000 = "
"(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
LongDoubleBits negone(-1.0l);
EXPECT_TRUE(negone.is_neg());
- EXPECT_EQ(negone.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF) << 112);
+ EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negone.get_mantissa(), 0_u128);
+ EXPECT_EQ(negone.uintval(), 0xBFFF0000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(),
"0xBFFF0000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
LongDoubleBits num(1.125l);
EXPECT_TRUE(num.is_pos());
- EXPECT_EQ(num.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
- EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
+ EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(num.get_mantissa(), 0x2000'00000000'00000000'00000000_u128);
+ EXPECT_EQ(num.uintval(), 0x3FFF2000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(),
"0x3FFF2000000000000000000000000000 = "
"(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
LongDoubleBits negnum(-1.125l);
EXPECT_TRUE(negnum.is_neg());
- EXPECT_EQ(negnum.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
- EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF2) << 108);
+ EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negnum.get_mantissa(), 0x2000'00000000'00000000'00000000_u128);
+ EXPECT_EQ(negnum.uintval(), 0xBFFF2000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFFF2000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
@@ -587,7 +575,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
}
#endif
-#if defined(LIBC_COMPILER_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_FLOAT128)
TEST(LlvmLibcFPBitsTest, Float128Type) {
using Float128Bits = FPBits<float128>;
@@ -600,57 +588,54 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
Float128Bits zero = Float128Bits::zero(Sign::POS);
EXPECT_TRUE(zero.is_pos());
- EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
+ EXPECT_EQ(zero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(zero.get_mantissa(), 0_u128);
+ EXPECT_EQ(zero.uintval(), 0_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(),
"0x00000000000000000000000000000000 = "
"(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
Float128Bits negzero = Float128Bits::zero(Sign::NEG);
EXPECT_TRUE(negzero.is_neg());
- EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
- EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 127);
+ EXPECT_EQ(negzero.get_biased_exponent(), 0_u16);
+ EXPECT_EQ(negzero.get_mantissa(), 0_u128);
+ EXPECT_EQ(negzero.uintval(), 0x80000000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(),
"0x80000000000000000000000000000000 = "
"(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)");
Float128Bits one(float128(1.0));
EXPECT_TRUE(one.is_pos());
- EXPECT_EQ(one.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
- EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
+ EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(one.get_mantissa(), 0_u128);
+ EXPECT_EQ(one.uintval(), 0x3FFF0000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(),
"0x3FFF0000000000000000000000000000 = "
"(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
Float128Bits negone(float128(-1.0));
EXPECT_TRUE(negone.is_neg());
- EXPECT_EQ(negone.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
- << 64);
- EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF) << 112);
+ EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negone.get_mantissa(), 0_u128);
+ EXPECT_EQ(negone.uintval(), 0xBFFF0000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(),
"0xBFFF0000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
Float128Bits num(float128(1.125));
EXPECT_TRUE(num.is_pos());
- EXPECT_EQ(num.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
- EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
+ EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(num.get_mantissa(), 0x2000'00000000'00000000'00000000_u128);
+ EXPECT_EQ(num.uintval(), 0x3FFF2000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(),
"0x3FFF2000000000000000000000000000 = "
"(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
Float128Bits negnum(float128(-1.125));
EXPECT_TRUE(negnum.is_neg());
- EXPECT_EQ(negnum.get_biased_exponent(), static_cast<uint16_t>(0x3FFF));
- EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
- EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF2) << 108);
+ EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16);
+ EXPECT_EQ(negnum.get_mantissa(), 0x2000'00000000'00000000'00000000_u128);
+ EXPECT_EQ(negnum.uintval(), 0xBFFF2000'00000000'00000000'00000000_u128);
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFFF2000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
@@ -658,4 +643,4 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
Float128Bits quiet_nan = Float128Bits::quiet_nan();
EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
}
-#endif // LIBC_COMPILER_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_FLOAT128
diff --git a/test/src/__support/RPC/rpc_smoke_test.cpp b/test/src/__support/RPC/rpc_smoke_test.cpp
index 54821e21f9cc..58b318c7cfa6 100644
--- a/test/src/__support/RPC/rpc_smoke_test.cpp
+++ b/test/src/__support/RPC/rpc_smoke_test.cpp
@@ -13,12 +13,8 @@
namespace {
enum { lane_size = 8, port_count = 4 };
-struct Packet {
- uint64_t unused;
-};
-
-using ProcAType = LIBC_NAMESPACE::rpc::Process<false, Packet>;
-using ProcBType = LIBC_NAMESPACE::rpc::Process<true, Packet>;
+using ProcAType = LIBC_NAMESPACE::rpc::Process<false>;
+using ProcBType = LIBC_NAMESPACE::rpc::Process<true>;
static_assert(ProcAType::inbox_offset(port_count) ==
ProcBType::outbox_offset(port_count));
@@ -26,7 +22,7 @@ static_assert(ProcAType::inbox_offset(port_count) ==
static_assert(ProcAType::outbox_offset(port_count) ==
ProcBType::inbox_offset(port_count));
-enum { alloc_size = ProcAType::allocation_size(port_count) };
+enum { alloc_size = ProcAType::allocation_size(port_count, 1) };
alignas(64) char buffer[alloc_size] = {0};
} // namespace
diff --git a/test/src/__support/arg_list_test.cpp b/test/src/__support/arg_list_test.cpp
index 1876cf7f70b4..4f229e2bfe69 100644
--- a/test/src/__support/arg_list_test.cpp
+++ b/test/src/__support/arg_list_test.cpp
@@ -120,7 +120,7 @@ TEST(LlvmLibcArgListTest, TestStructTypes) {
}
// Test vector extensions from clang.
-#if LIBC_HAS_ATTRIBUTE(ext_vector_type)
+#if __has_attribute(ext_vector_type)
using int1 = int __attribute__((ext_vector_type(1)));
using int2 = int __attribute__((ext_vector_type(2)));
diff --git a/test/src/__support/blockstore_test.cpp b/test/src/__support/blockstore_test.cpp
index f62857275fe4..5fe8fef1b6ed 100644
--- a/test/src/__support/blockstore_test.cpp
+++ b/test/src/__support/blockstore_test.cpp
@@ -19,7 +19,7 @@ class LlvmLibcBlockStoreTest : public LIBC_NAMESPACE::testing::Test {
public:
template <size_t BLOCK_SIZE, size_t ELEMENT_COUNT, bool REVERSE>
void populate_and_iterate() {
- LIBC_NAMESPACE::cpp::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store;
+ LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store;
for (int i = 0; i < int(ELEMENT_COUNT); ++i)
ASSERT_TRUE(block_store.push_back({i, 2 * i, 3 * unsigned(i)}));
auto end = block_store.end();
@@ -38,12 +38,12 @@ public:
}
}
ASSERT_EQ(i, int(ELEMENT_COUNT));
- LIBC_NAMESPACE::cpp::BlockStore<Element, BLOCK_SIZE, REVERSE>::destroy(
+ LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE>::destroy(
&block_store);
}
template <bool REVERSE> void back_test() {
- using LIBC_NAMESPACE::cpp::BlockStore;
+ using LIBC_NAMESPACE::BlockStore;
BlockStore<int, 4, REVERSE> block_store;
for (int i = 0; i < 20; i++)
ASSERT_TRUE(block_store.push_back(i));
@@ -53,7 +53,7 @@ public:
}
template <bool REVERSE> void empty_test() {
- using LIBC_NAMESPACE::cpp::BlockStore;
+ using LIBC_NAMESPACE::BlockStore;
BlockStore<int, 2, REVERSE> block_store;
ASSERT_TRUE(block_store.empty());
diff --git a/test/src/__support/fixed_point/fx_bits_test.cpp b/test/src/__support/fixed_point/fx_bits_test.cpp
new file mode 100644
index 000000000000..3cbd800adc3c
--- /dev/null
+++ b/test/src/__support/fixed_point/fx_bits_test.cpp
@@ -0,0 +1,397 @@
+//===-- Unittests for the FXBits class ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "include/llvm-libc-macros/stdfix-macros.h"
+
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/integer_literals.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::fixed_point::FXBits;
+using LIBC_NAMESPACE::fixed_point::FXRep;
+
+using LIBC_NAMESPACE::operator""_u8;
+using LIBC_NAMESPACE::operator""_u16;
+using LIBC_NAMESPACE::operator""_u32;
+using LIBC_NAMESPACE::operator""_u64;
+
+class LlvmLibcFxBitsTest : public LIBC_NAMESPACE::testing::Test {
+public:
+ template <typename T> void testBitwiseOps() {
+ EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_and(T(0.75), T(0.375)), T(0.25));
+ EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_or(T(0.75), T(0.375)), T(0.875));
+ using StorageType = typename FXRep<T>::StorageType;
+ StorageType a = LIBC_NAMESPACE::cpp::bit_cast<StorageType>(T(0.75));
+ a = ~a;
+ EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_not(T(0.75)),
+ FXBits<T>(a).get_val());
+ }
+};
+
+// -------------------------------- SHORT TESTS --------------------------------
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortFract) {
+ auto bits_var = FXBits<unsigned short fract>(0b00000000_u8);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ // Since an unsigned fract has no sign or integral components, setting either
+ // should have no effect.
+
+ bits_var.set_sign(true);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ bits_var.set_integral(0xab);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ // but setting the fraction should work
+
+ bits_var.set_fraction(0xcd);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0xcd_u8);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned short fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortAccum) {
+ auto bits_var = FXBits<unsigned short accum>(0b00000000'00000000_u16);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_sign(true); // 0 sign bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_integral(0xabcd); // 8 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_fraction(0x21fe); // 8 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00fe_u16);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned short accum>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_ShortFract) {
+ auto bits_var = FXBits<short fract>(0b0'0000000_u8);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ bits_var.set_integral(0xab); // 0 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00_u8);
+
+ bits_var.set_fraction(0xcd); // 7 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
+ EXPECT_EQ(bits_var.get_fraction(), 0x4d_u8);
+
+ // Bitwise ops
+ testBitwiseOps<short fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_ShortAccum) {
+ auto bits_var = FXBits<short accum>(0b0'00000000'0000000_u16);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_integral(0xabcd); // 8 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_fraction(0x21fe); // 7 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x007e_u16);
+
+ // Bitwise ops
+ testBitwiseOps<short accum>();
+}
+
+// -------------------------------- NORMAL TESTS -------------------------------
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedFract) {
+ auto bits_var = FXBits<unsigned fract>(0b0000000000000000_u16);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_sign(true); // 0 sign bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_integral(0xabcd); // 0 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_fraction(0xef12); // 16 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0xef12_u16);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedAccum) {
+ auto bits_var =
+ FXBits<unsigned accum>(0b0000000000000000'0000000000000000_u32);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_sign(true); // 0 sign bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_integral(0xabcd); // 16 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_fraction(0xef12); // 16 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000ef12_u32);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned accum>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_Fract) {
+ auto bits_var = FXBits<fract>(0b0'000000000000000_u16);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_integral(0xabcd); // 0 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16);
+
+ bits_var.set_fraction(0xef12); // 15 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
+ EXPECT_EQ(bits_var.get_fraction(), 0x6f12_u16);
+
+ // Bitwise ops
+ testBitwiseOps<fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_Accum) {
+ auto bits_var = FXBits<accum>(0b0'0000000000000000'000000000000000_u32);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_integral(0xabcd); // 16 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_fraction(0xef12); // 15 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00006f12_u32);
+
+ // Bitwise ops
+ testBitwiseOps<accum>();
+}
+
+// --------------------------------- LONG TESTS --------------------------------
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongFract) {
+ auto bits_var =
+ FXBits<unsigned long fract>(0b00000000000000000000000000000000_u32);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_sign(true); // 0 sign bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_integral(0xabcdef12); // 0 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_fraction(0xfedcba98); // 32 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0xfedcba98_u32);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned long fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongAccum) {
+ auto bits_var = FXBits<unsigned long accum>(
+ 0b00000000000000000000000000000000'00000000000000000000000000000000_u64);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_sign(true); // 0 sign bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_integral(0xabcdef12); // 32 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_fraction(0xfedcba98); // 32 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000fedcba98_u64);
+
+ // Bitwise ops
+ testBitwiseOps<unsigned long accum>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_LongFract) {
+ auto bits_var = FXBits<long fract>(0b0'0000000000000000000000000000000_u32);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_integral(0xabcdef12); // 0 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32);
+
+ bits_var.set_fraction(0xfedcba98); // 31 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
+ EXPECT_EQ(bits_var.get_fraction(), 0x7edcba98_u32);
+
+ // Bitwise ops
+ testBitwiseOps<long fract>();
+}
+
+TEST_F(LlvmLibcFxBitsTest, FXBits_LongAccum) {
+ auto bits_var = FXBits<long accum>(
+ 0b0'00000000000000000000000000000000'0000000000000000000000000000000_u64);
+
+ EXPECT_EQ(bits_var.get_sign(), false);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_sign(true); // 1 sign bit used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_integral(0xabcdef12); // 32 integral bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64);
+
+ bits_var.set_fraction(0xfedcba98); // 31 fractional bits used
+
+ EXPECT_EQ(bits_var.get_sign(), true);
+ EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
+ EXPECT_EQ(bits_var.get_fraction(), 0x000000007edcba98_u64);
+
+ // Bitwise ops
+ testBitwiseOps<long accum>();
+}
diff --git a/test/src/__support/fixedvector_test.cpp b/test/src/__support/fixedvector_test.cpp
index a70ebfabed22..4e92081321de 100644
--- a/test/src/__support/fixedvector_test.cpp
+++ b/test/src/__support/fixedvector_test.cpp
@@ -43,3 +43,19 @@ TEST(LlvmLibcFixedVectorTest, Destroy) {
LIBC_NAMESPACE::FixedVector<int, 20>::destroy(&fixed_vector);
ASSERT_TRUE(fixed_vector.empty());
}
+
+TEST(LlvmLibcFixedVectorTest, Iteration) {
+ LIBC_NAMESPACE::FixedVector<int, 20> v;
+ for (int i = 0; i < 3; i++)
+ v.push_back(i);
+ auto it = v.rbegin();
+ ASSERT_EQ(*it, 2);
+ ASSERT_EQ(*++it, 1);
+ ASSERT_EQ(*++it, 0);
+ // TODO: need an overload of Test::test for iterators?
+ // ASSERT_EQ(++it, v.rend());
+ // ASSERT_EQ(v.rbegin(), v.rbegin());
+ ASSERT_TRUE(++it == v.rend());
+ for (auto it = v.rbegin(), e = v.rend(); it != e; ++it)
+ ASSERT_GT(*it, -1);
+}
diff --git a/test/src/__support/high_precision_decimal_test.cpp b/test/src/__support/high_precision_decimal_test.cpp
index a9c039e45774..2bb28bcdab02 100644
--- a/test/src/__support/high_precision_decimal_test.cpp
+++ b/test/src/__support/high_precision_decimal_test.cpp
@@ -406,3 +406,31 @@ TEST(LlvmLibcHighPrecisionDecimalTest, BigExpTest) {
// Same, but since the number is negative the net result is -123456788
EXPECT_EQ(big_negative_hpd.get_decimal_point(), -123456789 + 1);
}
+
+TEST(LlvmLibcHighPrecisionDecimalTest, NumLenExpTest) {
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789", 5);
+
+ // The length of 5 includes things like the "e" so it only gets 3 digits of
+ // exponent.
+ EXPECT_EQ(hpd.get_decimal_point(), 123 + 1);
+
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal negative_hpd =
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789", 5);
+
+ // The negative sign also counts as a character.
+ EXPECT_EQ(negative_hpd.get_decimal_point(), -12 + 1);
+}
+
+TEST(LlvmLibcHighPrecisionDecimalTest, NumLenDigitsTest) {
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 5);
+
+ EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(12345));
+
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal longer_hpd =
+ LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 10);
+
+ // With 10 characters it should see the e, but not actually act on it.
+ EXPECT_EQ(longer_hpd.round_to_integer_type<uint64_t>(), uint64_t(123456789));
+}
diff --git a/test/src/__support/integer_literals_test.cpp b/test/src/__support/integer_literals_test.cpp
new file mode 100644
index 000000000000..cbc906aa7c99
--- /dev/null
+++ b/test/src/__support/integer_literals_test.cpp
@@ -0,0 +1,156 @@
+
+//===-- Unittests for user defined integer literals -----------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/integer_literals.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::operator""_u8;
+using LIBC_NAMESPACE::operator""_u16;
+using LIBC_NAMESPACE::operator""_u32;
+using LIBC_NAMESPACE::operator""_u64;
+using LIBC_NAMESPACE::operator""_u128;
+using LIBC_NAMESPACE::operator""_u256;
+
+TEST(LlvmLibcIntegerLiteralTest, u8) {
+ EXPECT_EQ(uint8_t(0), 0_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u16) {
+ EXPECT_EQ(uint16_t(0), 0_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u32) {
+ EXPECT_EQ(uint32_t(0), 0_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u64) {
+ EXPECT_EQ(uint64_t(0), 0_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64);
+ EXPECT_EQ(
+ uint64_t(UINT64_MAX),
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u128) {
+#ifdef LIBC_TYPES_HAS_INT128
+ const __uint128_t ZERO = 0;
+ const __uint128_t U8_MAX = UINT8_MAX;
+ const __uint128_t U16_MAX = UINT16_MAX;
+ const __uint128_t U32_MAX = UINT32_MAX;
+ const __uint128_t U64_MAX = UINT64_MAX;
+ const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX;
+#else
+ const UInt128 ZERO = 0;
+ const UInt128 U8_MAX = UINT8_MAX;
+ const UInt128 U16_MAX = UINT16_MAX;
+ const UInt128 U32_MAX = UINT32_MAX;
+ const UInt128 U64_MAX = UINT64_MAX;
+ const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
+#endif // LIBC_TYPES_HAS_INT128
+ EXPECT_EQ(ZERO, 0_u128);
+ EXPECT_EQ(U8_MAX, 255_u128);
+ EXPECT_EQ(U8_MAX, 0xFF_u128);
+ EXPECT_EQ(U8_MAX, 0b11111111_u128);
+ EXPECT_EQ(U16_MAX, 65535_u128);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u128);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128);
+ EXPECT_EQ(U32_MAX, 4294967295_u128);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u128);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U128_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u256) {
+ using UInt256 = LIBC_NAMESPACE::UInt<256>;
+ const UInt256 ZERO = 0;
+ const UInt256 U8_MAX = UINT8_MAX;
+ const UInt256 U16_MAX = UINT16_MAX;
+ const UInt256 U32_MAX = UINT32_MAX;
+ const UInt256 U64_MAX = UINT64_MAX;
+ const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX;
+ const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX;
+ EXPECT_EQ(ZERO, 0_u256);
+ EXPECT_EQ(U8_MAX, 255_u256);
+ EXPECT_EQ(U8_MAX, 0xFF_u256);
+ EXPECT_EQ(U8_MAX, 0b11111111_u256);
+ EXPECT_EQ(U16_MAX, 65535_u256);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u256);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256);
+ EXPECT_EQ(U32_MAX, 4294967295_u256);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u256);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U256_MAX,
+ 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ struct {
+ const char *str;
+ T expected;
+ } constexpr TEST_CASES[] = {
+ {"0", 0}, {"-1", -1}, {"+1", 1}, {"-0xFF", -255}, {"-0b11", -3},
+ };
+ for (auto tc : TEST_CASES) {
+ T actual = LIBC_NAMESPACE::parse_bigint<T>(tc.str);
+ EXPECT_EQ(actual, tc.expected);
+ }
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint_invalid) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ const T expected; // default construction
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(nullptr), expected);
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(""), expected);
+}
diff --git a/test/src/__support/integer_to_string_test.cpp b/test/src/__support/integer_to_string_test.cpp
index c8913bf461bb..270fddd828b6 100644
--- a/test/src/__support/integer_to_string_test.cpp
+++ b/test/src/__support/integer_to_string_test.cpp
@@ -6,16 +6,16 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/span.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/UInt.h"
#include "src/__support/UInt128.h"
+#include "src/__support/integer_literals.h"
#include "src/__support/integer_to_string.h"
#include "test/UnitTest/Test.h"
-#include "limits.h"
-
using LIBC_NAMESPACE::IntegerToString;
using LIBC_NAMESPACE::cpp::span;
using LIBC_NAMESPACE::cpp::string_view;
@@ -24,6 +24,8 @@ using LIBC_NAMESPACE::radix::Custom;
using LIBC_NAMESPACE::radix::Dec;
using LIBC_NAMESPACE::radix::Hex;
using LIBC_NAMESPACE::radix::Oct;
+using LIBC_NAMESPACE::operator""_u128;
+using LIBC_NAMESPACE::operator""_u256;
#define EXPECT(type, value, string_value) \
{ \
@@ -204,11 +206,11 @@ TEST(LlvmLibcIntegerToStringTest, UINT128_Base_16) {
using type = IntegerToString<UInt128, Hex::WithWidth<32>>;
EXPECT(type, 0, "00000000000000000000000000000000");
EXPECT(type, 0x12345, "00000000000000000000000000012345");
- EXPECT(type, static_cast<UInt128>(0x1234) << 112,
+ EXPECT(type, 0x12340000'00000000'00000000'00000000_u128,
"12340000000000000000000000000000");
- EXPECT(type, static_cast<UInt128>(0x1234) << 48,
+ EXPECT(type, 0x00000000'00000000'12340000'00000000_u128,
"00000000000000001234000000000000");
- EXPECT(type, static_cast<UInt128>(0x1234) << 52,
+ EXPECT(type, 0x00000000'00000001'23400000'00000000_u128,
"00000000000000012340000000000000");
}
@@ -225,18 +227,28 @@ TEST(LlvmLibcIntegerToStringTest, UINT64_Base_36) {
}
TEST(LlvmLibcIntegerToStringTest, UINT256_Base_16) {
- using UInt256 = LIBC_NAMESPACE::cpp::UInt<256>;
+ using UInt256 = LIBC_NAMESPACE::UInt<256>;
using type = IntegerToString<UInt256, Hex::WithWidth<64>>;
- EXPECT(type, static_cast<UInt256>(0),
- "0000000000000000000000000000000000000000000000000000000000000000");
- EXPECT(type, static_cast<UInt256>(0x12345),
- "0000000000000000000000000000000000000000000000000000000000012345");
- EXPECT(type, static_cast<UInt256>(0x1234) << 112,
- "0000000000000000000000000000000012340000000000000000000000000000");
- EXPECT(type, static_cast<UInt256>(0x1234) << 116,
- "0000000000000000000000000000000123400000000000000000000000000000");
- EXPECT(type, static_cast<UInt256>(0x1234) << 240,
- "1234000000000000000000000000000000000000000000000000000000000000");
+ EXPECT(
+ type,
+ 0x0000000000000000000000000000000000000000000000000000000000000000_u256,
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ EXPECT(
+ type,
+ 0x0000000000000000000000000000000000000000000000000000000000012345_u256,
+ "0000000000000000000000000000000000000000000000000000000000012345");
+ EXPECT(
+ type,
+ 0x0000000000000000000000000000000012340000000000000000000000000000_u256,
+ "0000000000000000000000000000000012340000000000000000000000000000");
+ EXPECT(
+ type,
+ 0x0000000000000000000000000000000123400000000000000000000000000000_u256,
+ "0000000000000000000000000000000123400000000000000000000000000000");
+ EXPECT(
+ type,
+ 0x1234000000000000000000000000000000000000000000000000000000000000_u256,
+ "1234000000000000000000000000000000000000000000000000000000000000");
}
TEST(LlvmLibcIntegerToStringTest, NegativeInterpretedAsPositive) {
diff --git a/test/src/__support/math_extras_test.cpp b/test/src/__support/math_extras_test.cpp
index e55d995592cc..401e631ea4ba 100644
--- a/test/src/__support/math_extras_test.cpp
+++ b/test/src/__support/math_extras_test.cpp
@@ -6,34 +6,156 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/UInt128.h" // UInt<128>
+#include "src/__support/integer_literals.h"
#include "src/__support/math_extras.h"
#include "test/UnitTest/Test.h"
namespace LIBC_NAMESPACE {
+// TODO: add UInt<128> support.
+using UnsignedTypesNoBigInt = testing::TypeList<
+#if defined(LIBC_TYPES_HAS_INT128)
+ __uint128_t,
+#endif // LIBC_TYPES_HAS_INT128
+ unsigned char, unsigned short, unsigned int, unsigned long,
+ unsigned long long, UInt<128>>;
+
TEST(LlvmLibcBlockMathExtrasTest, mask_trailing_ones) {
- EXPECT_EQ(uint8_t(0), (mask_leading_ones<uint8_t, 0>()));
- EXPECT_EQ(uint8_t(0), (mask_trailing_ones<uint8_t, 0>()));
- EXPECT_EQ(uint16_t(0), (mask_leading_ones<uint16_t, 0>()));
- EXPECT_EQ(uint16_t(0), (mask_trailing_ones<uint16_t, 0>()));
- EXPECT_EQ(uint32_t(0), (mask_leading_ones<uint32_t, 0>()));
- EXPECT_EQ(uint32_t(0), (mask_trailing_ones<uint32_t, 0>()));
- EXPECT_EQ(uint64_t(0), (mask_leading_ones<uint64_t, 0>()));
- EXPECT_EQ(uint64_t(0), (mask_trailing_ones<uint64_t, 0>()));
-
- EXPECT_EQ(uint32_t(0x00000003), (mask_trailing_ones<uint32_t, 2>()));
- EXPECT_EQ(uint32_t(0xC0000000), (mask_leading_ones<uint32_t, 2>()));
-
- EXPECT_EQ(uint32_t(0x000007FF), (mask_trailing_ones<uint32_t, 11>()));
- EXPECT_EQ(uint32_t(0xFFE00000), (mask_leading_ones<uint32_t, 11>()));
-
- EXPECT_EQ(uint32_t(0xFFFFFFFF), (mask_trailing_ones<uint32_t, 32>()));
- EXPECT_EQ(uint32_t(0xFFFFFFFF), (mask_leading_ones<uint32_t, 32>()));
- EXPECT_EQ(uint64_t(0xFFFFFFFFFFFFFFFF), (mask_trailing_ones<uint64_t, 64>()));
- EXPECT_EQ(uint64_t(0xFFFFFFFFFFFFFFFF), (mask_leading_ones<uint64_t, 64>()));
-
- EXPECT_EQ(uint64_t(0x0000FFFFFFFFFFFF), (mask_trailing_ones<uint64_t, 48>()));
- EXPECT_EQ(uint64_t(0xFFFFFFFFFFFF0000), (mask_leading_ones<uint64_t, 48>()));
+ EXPECT_EQ(0_u8, (mask_leading_ones<uint8_t, 0>()));
+ EXPECT_EQ(0_u8, (mask_trailing_ones<uint8_t, 0>()));
+ EXPECT_EQ(0_u16, (mask_leading_ones<uint16_t, 0>()));
+ EXPECT_EQ(0_u16, (mask_trailing_ones<uint16_t, 0>()));
+ EXPECT_EQ(0_u32, (mask_leading_ones<uint32_t, 0>()));
+ EXPECT_EQ(0_u32, (mask_trailing_ones<uint32_t, 0>()));
+ EXPECT_EQ(0_u64, (mask_leading_ones<uint64_t, 0>()));
+ EXPECT_EQ(0_u64, (mask_trailing_ones<uint64_t, 0>()));
+
+ EXPECT_EQ(0x00000003_u32, (mask_trailing_ones<uint32_t, 2>()));
+ EXPECT_EQ(0xC0000000_u32, (mask_leading_ones<uint32_t, 2>()));
+
+ EXPECT_EQ(0x000007FF_u32, (mask_trailing_ones<uint32_t, 11>()));
+ EXPECT_EQ(0xFFE00000_u32, (mask_leading_ones<uint32_t, 11>()));
+
+ EXPECT_EQ(0xFFFFFFFF_u32, (mask_trailing_ones<uint32_t, 32>()));
+ EXPECT_EQ(0xFFFFFFFF_u32, (mask_leading_ones<uint32_t, 32>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFF_u64, (mask_trailing_ones<uint64_t, 64>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFF_u64, (mask_leading_ones<uint64_t, 64>()));
+
+ EXPECT_EQ(0x0000FFFFFFFFFFFF_u64, (mask_trailing_ones<uint64_t, 48>()));
+ EXPECT_EQ(0xFFFFFFFFFFFF0000_u64, (mask_leading_ones<uint64_t, 48>()));
+
+ EXPECT_EQ(0_u128, (mask_trailing_ones<UInt128, 0>()));
+ EXPECT_EQ(0_u128, (mask_leading_ones<UInt128, 0>()));
+
+ EXPECT_EQ(0x00000000000000007FFFFFFFFFFFFFFF_u128,
+ (mask_trailing_ones<UInt128, 63>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFE0000000000000000_u128,
+ (mask_leading_ones<UInt128, 63>()));
+
+ EXPECT_EQ(0x0000000000000000FFFFFFFFFFFFFFFF_u128,
+ (mask_trailing_ones<UInt128, 64>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFF0000000000000000_u128,
+ (mask_leading_ones<UInt128, 64>()));
+
+ EXPECT_EQ(0x0000000000000001FFFFFFFFFFFFFFFF_u128,
+ (mask_trailing_ones<UInt128, 65>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFF8000000000000000_u128,
+ (mask_leading_ones<UInt128, 65>()));
+
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128,
+ (mask_trailing_ones<UInt128, 128>()));
+ EXPECT_EQ(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128,
+ (mask_leading_ones<UInt128, 128>()));
+}
+
+TYPED_TEST(LlvmLibcBitTest, FirstLeadingZero, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(first_leading_zero<T>(cpp::numeric_limits<T>::max()), 0);
+ for (int i = 0U; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(first_leading_zero<T>(~(T(1) << i)),
+ cpp::numeric_limits<T>::digits - i);
+}
+
+TYPED_TEST(LlvmLibcBitTest, FirstLeadingOne, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(first_leading_one<T>(static_cast<T>(0)), 0);
+ for (int i = 0U; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(first_leading_one<T>(T(1) << i),
+ cpp::numeric_limits<T>::digits - i);
+}
+
+TYPED_TEST(LlvmLibcBitTest, FirstTrailingZero, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(first_trailing_zero<T>(cpp::numeric_limits<T>::max()), 0);
+ for (int i = 0U; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(first_trailing_zero<T>(~(T(1) << i)), i + 1);
+}
+
+TYPED_TEST(LlvmLibcBitTest, FirstTrailingOne, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(first_trailing_one<T>(cpp::numeric_limits<T>::max()), 0);
+ for (int i = 0U; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(first_trailing_one<T>(T(1) << i), i + 1);
+}
+
+TYPED_TEST(LlvmLibcBitTest, CountZeros, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(count_zeros(T(0)), cpp::numeric_limits<T>::digits);
+ for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i)
+ EXPECT_EQ(count_zeros<T>(cpp::numeric_limits<T>::max() >> i), i);
+}
+
+using UnsignedTypes = testing::TypeList<
+#if defined(__SIZEOF_INT128__)
+ __uint128_t,
+#endif
+ unsigned char, unsigned short, unsigned int, unsigned long,
+ unsigned long long>;
+
+TYPED_TEST(LlvmLibcBlockMathExtrasTest, add_overflow, UnsignedTypes) {
+ constexpr T ZERO = cpp::numeric_limits<T>::min();
+ constexpr T ONE(1);
+ constexpr T MAX = cpp::numeric_limits<T>::max();
+ constexpr T BEFORE_MAX = MAX - 1;
+
+ const struct {
+ T lhs;
+ T rhs;
+ T sum;
+ bool carry;
+ } TESTS[] = {
+ {ZERO, ONE, ONE, false}, // 0x00 + 0x01 = 0x01
+ {BEFORE_MAX, ONE, MAX, false}, // 0xFE + 0x01 = 0xFF
+ {MAX, ONE, ZERO, true}, // 0xFF + 0x01 = 0x00 (carry)
+ {MAX, MAX, BEFORE_MAX, true}, // 0xFF + 0xFF = 0xFE (carry)
+ };
+ for (auto tc : TESTS) {
+ T sum;
+ bool carry = add_overflow<T>(tc.lhs, tc.rhs, sum);
+ EXPECT_EQ(sum, tc.sum);
+ EXPECT_EQ(carry, tc.carry);
+ }
+}
+
+TYPED_TEST(LlvmLibcBlockMathExtrasTest, sub_overflow, UnsignedTypes) {
+ constexpr T ZERO = cpp::numeric_limits<T>::min();
+ constexpr T ONE(1);
+ constexpr T MAX = cpp::numeric_limits<T>::max();
+ constexpr T BEFORE_MAX = MAX - 1;
+
+ const struct {
+ T lhs;
+ T rhs;
+ T sub;
+ bool carry;
+ } TESTS[] = {
+ {ONE, ZERO, ONE, false}, // 0x01 - 0x00 = 0x01
+ {MAX, MAX, ZERO, false}, // 0xFF - 0xFF = 0x00
+ {ZERO, ONE, MAX, true}, // 0x00 - 0x01 = 0xFF (carry)
+ {BEFORE_MAX, MAX, MAX, true}, // 0xFE - 0xFF = 0xFF (carry)
+ };
+ for (auto tc : TESTS) {
+ T sub;
+ bool carry = sub_overflow<T>(tc.lhs, tc.rhs, sub);
+ EXPECT_EQ(sub, tc.sub);
+ EXPECT_EQ(carry, tc.carry);
+ }
}
} // namespace LIBC_NAMESPACE
diff --git a/test/src/__support/memory_size_test.cpp b/test/src/__support/memory_size_test.cpp
index 93ef3711d40e..1c8f1ce87415 100644
--- a/test/src/__support/memory_size_test.cpp
+++ b/test/src/__support/memory_size_test.cpp
@@ -49,6 +49,13 @@ TEST(LlvmLibcMemSizeTest, Addition) {
ASSERT_FALSE((max + SafeMemSize{static_cast<size_t>(1)}).valid());
ASSERT_FALSE((third + third + third + third).valid());
ASSERT_FALSE((half + half + half).valid());
+
+ ASSERT_FALSE((SafeMemSize{static_cast<size_t>(-1)} +
+ SafeMemSize{static_cast<size_t>(2)})
+ .valid());
+ ASSERT_FALSE((SafeMemSize{static_cast<size_t>(2)} +
+ SafeMemSize{static_cast<size_t>(-1)})
+ .valid());
}
TEST(LlvmLibcMemSizeTest, Multiplication) {
diff --git a/test/src/__support/str_to_double_test.cpp b/test/src/__support/str_to_double_test.cpp
index b66935f0988e..3c6d03978803 100644
--- a/test/src/__support/str_to_double_test.cpp
+++ b/test/src/__support/str_to_double_test.cpp
@@ -90,7 +90,7 @@ TEST(LlvmLibcStrToDblTest, SimpleDecimalConversionExtraTypes) {
uint64_t double_output_mantissa = 0;
uint32_t output_exp2 = 0;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
auto double_result =
internal::simple_decimal_conversion<double>("123456789012345678900");
diff --git a/test/src/__support/str_to_float_test.cpp b/test/src/__support/str_to_float_test.cpp
index 3102fa7aa91e..f23d8706d77d 100644
--- a/test/src/__support/str_to_float_test.cpp
+++ b/test/src/__support/str_to_float_test.cpp
@@ -46,7 +46,7 @@ TEST(LlvmLibcStrToFltTest, SimpleDecimalConversionExtraTypes) {
uint32_t float_output_mantissa = 0;
uint32_t output_exp2 = 0;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
auto float_result =
internal::simple_decimal_conversion<float>("123456789012345678900");
float_output_mantissa = float_result.num.mantissa;
diff --git a/test/src/__support/str_to_fp_test.h b/test/src/__support/str_to_fp_test.h
index 32a313309392..bddff035fdd1 100644
--- a/test/src/__support/str_to_fp_test.h
+++ b/test/src/__support/str_to_fp_test.h
@@ -66,7 +66,7 @@ template <typename T> struct LlvmLibcStrToFloatTest : public testing::Test {
const int expectedErrno = 0) {
StorageType actual_output_mantissa = 0;
uint32_t actual_output_exp2 = 0;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
auto result = internal::simple_decimal_conversion<T>(numStart);
diff --git a/test/src/__support/str_to_integer_test.cpp b/test/src/__support/str_to_integer_test.cpp
new file mode 100644
index 000000000000..34b645b4b38c
--- /dev/null
+++ b/test/src/__support/str_to_integer_test.cpp
@@ -0,0 +1,240 @@
+//===-- Unittests for str_to_integer --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/str_to_integer.h"
+#include "src/errno/libc_errno.h"
+#include <stddef.h>
+
+#include "test/UnitTest/Test.h"
+
+// This file is for testing the src_len argument and other internal interface
+// features. Primary testing is done in stdlib/StrolTest.cpp through the public
+// interface.
+
+TEST(LlvmLibcStrToIntegerTest, SimpleLength) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("12345", 10, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
+ ASSERT_EQ(result.value, 12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("12345", 10, 2);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(2));
+ ASSERT_EQ(result.value, 12);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("12345", 10, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, LeadingSpaces) {
+ auto result =
+ LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 15);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
+ ASSERT_EQ(result.value, 12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
+ ASSERT_EQ(result.value, 12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 7);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
+ ASSERT_EQ(result.value, 12);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 5);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, LeadingSign) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("+12345", 10, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("-12345", 10, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, -12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("+12345", 10, 6);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("-12345", 10, 6);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, -12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("+12345", 10, 3);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(3));
+ ASSERT_EQ(result.value, 12);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("-12345", 10, 3);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(3));
+ ASSERT_EQ(result.value, -12);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("+12345", 10, 1);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("-12345", 10, 1);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("+12345", 10, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("-12345", 10, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, Base16PrefixAutoSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 0, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
+ ASSERT_EQ(result.value, 0x12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 0, 7);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
+ ASSERT_EQ(result.value, 0x12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 0, 5);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
+ ASSERT_EQ(result.value, 0x123);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 0, 2);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 0, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, Base16PrefixManualSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 16, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
+ ASSERT_EQ(result.value, 0x12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 16, 7);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
+ ASSERT_EQ(result.value, 0x12345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 16, 5);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
+ ASSERT_EQ(result.value, 0x123);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 16, 2);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("0x12345", 16, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, Base8PrefixAutoSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 0, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 012345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 0, 6);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 012345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 0, 4);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(4));
+ ASSERT_EQ(result.value, 0123);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 0, 1);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 0, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, Base8PrefixManualSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 8, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 012345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 8, 6);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 012345);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 8, 4);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(4));
+ ASSERT_EQ(result.value, 0123);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 8, 1);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
+ ASSERT_EQ(result.value, 0);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>("012345", 8, 0);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
+ ASSERT_EQ(result.value, 0);
+}
+
+TEST(LlvmLibcStrToIntegerTest, CombinedTests) {
+ auto result =
+ LIBC_NAMESPACE::internal::strtointeger<int>(" -0x123", 0, 10);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
+ ASSERT_EQ(result.value, -0x123);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" -0x123", 0, 8);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(8));
+ ASSERT_EQ(result.value, -0x1);
+
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(" -0x123", 0, 7);
+ EXPECT_FALSE(result.has_error());
+ EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
+ ASSERT_EQ(result.value, 0);
+}
diff --git a/test/src/__support/str_to_long_double_test.cpp b/test/src/__support/str_to_long_double_test.cpp
index 6fefc89ac3a9..c97fe27565e8 100644
--- a/test/src/__support/str_to_long_double_test.cpp
+++ b/test/src/__support/str_to_long_double_test.cpp
@@ -1,16 +1,19 @@
#include "str_to_fp_test.h"
+#include "src/__support/integer_literals.h"
+
namespace LIBC_NAMESPACE {
using LlvmLibcStrToLongDblTest = LlvmLibcStrToFloatTest<long double>;
+using LIBC_NAMESPACE::operator""_u128;
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat64AsLongDouble) {
eisel_lemire_test(123, 0, 0x1EC00000000000, 1029);
}
-#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Simple) {
eisel_lemire_test(123, 0, 0xf600000000000000, 16389);
@@ -18,15 +21,12 @@ TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Simple) {
}
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80LongerMantissa) {
- eisel_lemire_test((UInt128(0x1234567812345678) << 64) +
- UInt128(0x1234567812345678),
- 0, 0x91a2b3c091a2b3c1, 16507);
- eisel_lemire_test((UInt128(0x1234567812345678) << 64) +
- UInt128(0x1234567812345678),
- 300, 0xd97757de56adb65c, 17503);
- eisel_lemire_test((UInt128(0x1234567812345678) << 64) +
- UInt128(0x1234567812345678),
- -300, 0xc30feb9a7618457d, 15510);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 0,
+ 0x91a2b3c091a2b3c1, 16507);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 300,
+ 0xd97757de56adb65c, 17503);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, -300,
+ 0xc30feb9a7618457d, 15510);
}
// These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table.
@@ -54,35 +54,31 @@ TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Fallback) {
ASSERT_FALSE(internal::eisel_lemire<long double>({1, -1000}).has_value());
}
-#else // Quad precision long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Simple) {
- eisel_lemire_test(123, 0, (UInt128(0x1ec0000000000) << 64), 16389);
- eisel_lemire_test(
- 12345678901234568192u, 0,
- (UInt128(0x156a95319d63e) << 64) + UInt128(0x1800000000000000), 16446);
+ eisel_lemire_test(123, 0, 0x1ec00'00000000'00000000'00000000_u128, 16389);
+ eisel_lemire_test(12345678901234568192u, 0,
+ 0x156a9'5319d63e'18000000'00000000_u128, 16446);
}
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128LongerMantissa) {
- eisel_lemire_test(
- (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 0,
- (UInt128(0x1234567812345) << 64) + UInt128(0x6781234567812345), 16507);
- eisel_lemire_test(
- (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 300,
- (UInt128(0x1b2eeafbcad5b) << 64) + UInt128(0x6cb8b4451dfcde19), 17503);
- eisel_lemire_test(
- (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), -300,
- (UInt128(0x1861fd734ec30) << 64) + UInt128(0x8afa7189f0f7595f), 15510);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 0,
+ 0x12345'67812345'67812345'67812345_u128, 16507);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, 300,
+ 0x1b2ee'afbcad5b'6cb8b445'1dfcde19_u128, 17503);
+ eisel_lemire_test(0x12345678'12345678'12345678'12345678_u128, -300,
+ 0x1861f'd734ec30'8afa7189'f0f7595f_u128, 15510);
}
TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Fallback) {
- ASSERT_FALSE(
- internal::eisel_lemire<long double>(
- {(UInt128(0x5ce0e9a56015fec5) << 64) + UInt128(0xaadfa328ae39b333),
- 1})
- .has_value());
+ ASSERT_FALSE(internal::eisel_lemire<long double>(
+ {0x5ce0e9a5'6015fec5'aadfa328'ae39b333_u128, 1})
+ .has_value());
}
+#else
+#error "Unknown long double type"
#endif
} // namespace LIBC_NAMESPACE
diff --git a/test/src/__support/uint_test.cpp b/test/src/__support/uint_test.cpp
index 0ad72c35645c..5696e54c73f3 100644
--- a/test/src/__support/uint_test.cpp
+++ b/test/src/__support/uint_test.cpp
@@ -8,25 +8,216 @@
#include "src/__support/CPP/optional.h"
#include "src/__support/UInt.h"
+#include "src/__support/integer_literals.h" // parse_unsigned_bigint
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
+#include "include/llvm-libc-macros/math-macros.h" // HUGE_VALF, HUGE_VALF
#include "test/UnitTest/Test.h"
-#include <math.h> // HUGE_VALF, HUGE_VALF
namespace LIBC_NAMESPACE {
-using LL_UInt64 = cpp::UInt<64>;
-// We want to test cpp::UInt<128> explicitly. So, for
+enum Value { ZERO, ONE, TWO, MIN, MAX };
+
+template <typename T> auto create(Value value) {
+ switch (value) {
+ case ZERO:
+ return T(0);
+ case ONE:
+ return T(1);
+ case TWO:
+ return T(2);
+ case MIN:
+ return T::min();
+ case MAX:
+ return T::max();
+ }
+}
+
+using Types = testing::TypeList< //
+#ifdef LIBC_TYPES_HAS_INT64
+ BigInt<64, false, uint64_t>, // 64-bits unsigned (1 x uint64_t)
+ BigInt<64, true, uint64_t>, // 64-bits signed (1 x uint64_t)
+#endif
+#ifdef LIBC_TYPES_HAS_INT128
+ BigInt<128, false, __uint128_t>, // 128-bits unsigned (1 x __uint128_t)
+ BigInt<128, true, __uint128_t>, // 128-bits signed (1 x __uint128_t)
+#endif
+ BigInt<16, false, uint16_t>, // 16-bits unsigned (1 x uint16_t)
+ BigInt<16, true, uint16_t>, // 16-bits signed (1 x uint16_t)
+ BigInt<64, false, uint16_t>, // 64-bits unsigned (4 x uint16_t)
+ BigInt<64, true, uint16_t> // 64-bits signed (4 x uint16_t)
+ >;
+
+#define ASSERT_SAME(A, B) ASSERT_TRUE((A) == (B))
+
+TYPED_TEST(LlvmLibcUIntClassTest, Additions, Types) {
+ ASSERT_SAME(create<T>(ZERO) + create<T>(ZERO), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ONE) + create<T>(ZERO), create<T>(ONE));
+ ASSERT_SAME(create<T>(ZERO) + create<T>(ONE), create<T>(ONE));
+ ASSERT_SAME(create<T>(ONE) + create<T>(ONE), create<T>(TWO));
+ // 2's complement addition works for signed and unsigned types.
+ // - unsigned : 0xff + 0x01 = 0x00 (255 + 1 = 0)
+ // - signed : 0xef + 0x01 = 0xf0 (127 + 1 = -128)
+ ASSERT_SAME(create<T>(MAX) + create<T>(ONE), create<T>(MIN));
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, Subtraction, Types) {
+ ASSERT_SAME(create<T>(ZERO) - create<T>(ZERO), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ONE) - create<T>(ONE), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ONE) - create<T>(ZERO), create<T>(ONE));
+ // 2's complement subtraction works for signed and unsigned types.
+ // - unsigned : 0x00 - 0x01 = 0xff ( 0 - 1 = 255)
+ // - signed : 0xf0 - 0x01 = 0xef (-128 - 1 = 127)
+ ASSERT_SAME(create<T>(MIN) - create<T>(ONE), create<T>(MAX));
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, Multiplication, Types) {
+ ASSERT_SAME(create<T>(ZERO) * create<T>(ZERO), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ZERO) * create<T>(ONE), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ONE) * create<T>(ZERO), create<T>(ZERO));
+ ASSERT_SAME(create<T>(ONE) * create<T>(ONE), create<T>(ONE));
+ ASSERT_SAME(create<T>(ONE) * create<T>(TWO), create<T>(TWO));
+ ASSERT_SAME(create<T>(TWO) * create<T>(ONE), create<T>(TWO));
+ // - unsigned : 0xff x 0xff = 0x01 (mod 0xff)
+ // - signed : 0xef x 0xef = 0x01 (mod 0xff)
+ ASSERT_SAME(create<T>(MAX) * create<T>(MAX), create<T>(ONE));
+}
+
+template <typename T> void print(const char *msg, T value) {
+ testing::tlog << msg;
+ IntegerToString<T, radix::Hex> buffer(value);
+ testing::tlog << buffer.view() << "\n";
+}
+
+TEST(LlvmLibcUIntClassTest, SignedAddSub) {
+ // Computations performed by https://www.wolframalpha.com/
+ using T = BigInt<128, true, uint32_t>;
+ const T a = parse_bigint<T>("1927508279017230597");
+ const T b = parse_bigint<T>("278789278723478925");
+ const T s = parse_bigint<T>("2206297557740709522");
+ // Addition
+ ASSERT_SAME(a + b, s);
+ ASSERT_SAME(b + a, s); // commutative
+ // Subtraction
+ ASSERT_SAME(a - s, -b);
+ ASSERT_SAME(s - a, b);
+}
+
+TEST(LlvmLibcUIntClassTest, SignedMulDiv) {
+ // Computations performed by https://www.wolframalpha.com/
+ using T = BigInt<128, true, uint16_t>;
+ struct {
+ const char *a;
+ const char *b;
+ const char *mul;
+ } const test_cases[] = {{"-4", "3", "-12"},
+ {"-3", "-3", "9"},
+ {"1927508279017230597", "278789278723478925",
+ "537368642840747885329125014794668225"}};
+ for (auto tc : test_cases) {
+ const T a = parse_bigint<T>(tc.a);
+ const T b = parse_bigint<T>(tc.b);
+ const T mul = parse_bigint<T>(tc.mul);
+ // Multiplication
+ ASSERT_SAME(a * b, mul);
+ ASSERT_SAME(b * a, mul); // commutative
+ ASSERT_SAME(a * -b, -mul); // sign
+ ASSERT_SAME(-a * b, -mul); // sign
+ ASSERT_SAME(-a * -b, mul); // sign
+ // Division
+ ASSERT_SAME(mul / a, b);
+ ASSERT_SAME(mul / b, a);
+ ASSERT_SAME(-mul / a, -b); // sign
+ ASSERT_SAME(mul / -a, -b); // sign
+ ASSERT_SAME(-mul / -a, b); // sign
+ }
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, Division, Types) {
+ ASSERT_SAME(create<T>(ZERO) / create<T>(ONE), create<T>(ZERO));
+ ASSERT_SAME(create<T>(MAX) / create<T>(ONE), create<T>(MAX));
+ ASSERT_SAME(create<T>(MAX) / create<T>(MAX), create<T>(ONE));
+ ASSERT_SAME(create<T>(ONE) / create<T>(ONE), create<T>(ONE));
+ if constexpr (T::SIGNED) {
+ // Special case found by fuzzing.
+ ASSERT_SAME(create<T>(MIN) / create<T>(MIN), create<T>(ONE));
+ }
+ // - unsigned : 0xff / 0x02 = 0x7f
+ // - signed : 0xef / 0x02 = 0x77
+ ASSERT_SAME(create<T>(MAX) / create<T>(TWO), (create<T>(MAX) >> 1));
+
+ using word_type = typename T::word_type;
+ const T zero_one_repeated = T::all_ones() / T(0xff);
+ const word_type pattern = word_type(~0) / word_type(0xff);
+ for (const word_type part : zero_one_repeated.val) {
+ if constexpr (T::SIGNED == false) {
+ EXPECT_EQ(part, pattern);
+ }
+ }
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, is_neg, Types) {
+ EXPECT_FALSE(create<T>(ZERO).is_neg());
+ EXPECT_FALSE(create<T>(ONE).is_neg());
+ EXPECT_FALSE(create<T>(TWO).is_neg());
+ EXPECT_EQ(create<T>(MIN).is_neg(), T::SIGNED);
+ EXPECT_FALSE(create<T>(MAX).is_neg());
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, Masks, Types) {
+ if constexpr (!T::SIGNED) {
+ constexpr size_t BITS = T::BITS;
+ // mask_trailing_ones
+ ASSERT_SAME((mask_trailing_ones<T, 0>()), T::zero());
+ ASSERT_SAME((mask_trailing_ones<T, 1>()), T::one());
+ ASSERT_SAME((mask_trailing_ones<T, BITS - 1>()), T::all_ones() >> 1);
+ ASSERT_SAME((mask_trailing_ones<T, BITS>()), T::all_ones());
+ // mask_leading_ones
+ ASSERT_SAME((mask_leading_ones<T, 0>()), T::zero());
+ ASSERT_SAME((mask_leading_ones<T, 1>()), T::one() << (BITS - 1));
+ ASSERT_SAME((mask_leading_ones<T, BITS - 1>()), T::all_ones() - T::one());
+ ASSERT_SAME((mask_leading_ones<T, BITS>()), T::all_ones());
+ // mask_trailing_zeros
+ ASSERT_SAME((mask_trailing_zeros<T, 0>()), T::all_ones());
+ ASSERT_SAME((mask_trailing_zeros<T, 1>()), T::all_ones() - T::one());
+ ASSERT_SAME((mask_trailing_zeros<T, BITS - 1>()), T::one() << (BITS - 1));
+ ASSERT_SAME((mask_trailing_zeros<T, BITS>()), T::zero());
+ // mask_trailing_zeros
+ ASSERT_SAME((mask_leading_zeros<T, 0>()), T::all_ones());
+ ASSERT_SAME((mask_leading_zeros<T, 1>()), T::all_ones() >> 1);
+ ASSERT_SAME((mask_leading_zeros<T, BITS - 1>()), T::one());
+ ASSERT_SAME((mask_leading_zeros<T, BITS>()), T::zero());
+ }
+}
+
+TYPED_TEST(LlvmLibcUIntClassTest, CountBits, Types) {
+ if constexpr (!T::SIGNED) {
+ for (size_t i = 0; i <= T::BITS; ++i) {
+ const auto l_one = T::all_ones() << i; // 0b111...000
+ const auto r_one = T::all_ones() >> i; // 0b000...111
+ const int zeros = i;
+ const int ones = T::BITS - zeros;
+ ASSERT_EQ(cpp::countr_one(r_one), ones);
+ ASSERT_EQ(cpp::countl_one(l_one), ones);
+ ASSERT_EQ(cpp::countr_zero(l_one), zeros);
+ ASSERT_EQ(cpp::countl_zero(r_one), zeros);
+ }
+ }
+}
+
+using LL_UInt64 = UInt<64>;
+// We want to test UInt<128> explicitly. So, for
// convenience, we use a sugar which does not conflict with the UInt128 type
// which can resolve to __uint128_t if the platform has it.
-using LL_UInt128 = cpp::UInt<128>;
-using LL_UInt192 = cpp::UInt<192>;
-using LL_UInt256 = cpp::UInt<256>;
-using LL_UInt320 = cpp::UInt<320>;
-using LL_UInt512 = cpp::UInt<512>;
-using LL_UInt1024 = cpp::UInt<1024>;
+using LL_UInt128 = UInt<128>;
+using LL_UInt192 = UInt<192>;
+using LL_UInt256 = UInt<256>;
+using LL_UInt320 = UInt<320>;
+using LL_UInt512 = UInt<512>;
+using LL_UInt1024 = UInt<1024>;
-using LL_Int128 = cpp::Int<128>;
-using LL_Int192 = cpp::Int<192>;
+using LL_Int128 = Int<128>;
+using LL_Int192 = Int<192>;
TEST(LlvmLibcUIntClassTest, BitCastToFromDouble) {
static_assert(cpp::is_trivially_copyable<LL_UInt64>::value);
@@ -41,7 +232,7 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromDouble) {
}
}
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
TEST(LlvmLibcUIntClassTest, BitCastToFromNativeUint128) {
static_assert(cpp::is_trivially_copyable<LL_UInt128>::value);
static_assert(sizeof(LL_UInt128) == sizeof(__uint128_t));
@@ -52,9 +243,9 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromNativeUint128) {
EXPECT_TRUE(value == forth);
}
}
-#endif
+#endif // LIBC_TYPES_HAS_INT128
-#ifdef LIBC_COMPILER_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_FLOAT128
TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) {
static_assert(cpp::is_trivially_copyable<LL_UInt128>::value);
static_assert(sizeof(LL_UInt128) == sizeof(float128));
@@ -65,7 +256,7 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) {
EXPECT_TRUE(value == forth);
}
}
-#endif
+#endif // LIBC_TYPES_HAS_FLOAT128
TEST(LlvmLibcUIntClassTest, BasicInit) {
LL_UInt128 half_val(12345);
@@ -560,7 +751,7 @@ TEST(LlvmLibcUIntClassTest, FullMulTests) {
LL_UInt##Bits a = ~LL_UInt##Bits(0); \
LL_UInt##Bits hi = a.quick_mul_hi(a); \
LL_UInt##Bits trunc = static_cast<LL_UInt##Bits>(a.ful_mul(a) >> Bits); \
- uint64_t overflow = trunc.sub(hi); \
+ uint64_t overflow = trunc.sub_overflow(hi); \
EXPECT_EQ(overflow, uint64_t(0)); \
EXPECT_LE(uint64_t(trunc), uint64_t(Error)); \
} while (0)
@@ -588,7 +779,7 @@ TEST(LlvmLibcUIntClassTest, ConstexprInitTests) {
d <<= e; \
LL_UInt320 q1 = y / d; \
LL_UInt320 r1 = y % d; \
- LL_UInt320 r2 = *y.div_uint32_times_pow_2(x, e); \
+ LL_UInt320 r2 = *y.div_uint_half_times_pow_2(x, e); \
EXPECT_EQ(q1, y); \
EXPECT_EQ(r1, r2); \
} while (0)
@@ -652,7 +843,7 @@ TEST(LlvmLibcUIntClassTest, BasicArithmeticInt128Tests) {
ASSERT_EQ(c * b, b);
}
-#ifdef __SIZEOF_INT128__
+#ifdef LIBC_TYPES_HAS_INT128
TEST(LlvmLibcUIntClassTest, ConstructorFromUInt128Tests) {
__uint128_t a = (__uint128_t(123) << 64) + 1;
@@ -676,6 +867,52 @@ TEST(LlvmLibcUIntClassTest, ConstructorFromUInt128Tests) {
ASSERT_EQ(LL_UInt192(e + f), LL_UInt192(a + b));
}
-#endif // __SIZEOF_INT128__
+TEST(LlvmLibcUIntClassTest, WordTypeUInt128Tests) {
+ using LL_UInt256_128 = BigInt<256, false, __uint128_t>;
+ using LL_UInt128_128 = BigInt<128, false, __uint128_t>;
+
+ LL_UInt256_128 a(1);
+
+ ASSERT_EQ(static_cast<int>(a), 1);
+ a = (a << 128) + 2;
+ ASSERT_EQ(static_cast<int>(a), 2);
+ ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(2));
+ a = (a << 32) + 3;
+ ASSERT_EQ(static_cast<int>(a), 3);
+ ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(0x2'0000'0003));
+ ASSERT_EQ(static_cast<int>(a >> 32), 2);
+ ASSERT_EQ(static_cast<int>(a >> (128 + 32)), 1);
+
+ LL_UInt128_128 b(__uint128_t(1) << 127);
+ LL_UInt128_128 c(b);
+ a = b.ful_mul(c);
+
+ ASSERT_EQ(static_cast<int>(a >> 254), 1);
+
+ LL_UInt256_128 d = LL_UInt256_128(123) << 4;
+ ASSERT_EQ(static_cast<int>(d), 123 << 4);
+ LL_UInt256_128 e = a / d;
+ LL_UInt256_128 f = a % d;
+ LL_UInt256_128 r = *a.div_uint_half_times_pow_2(123, 4);
+ EXPECT_TRUE(e == a);
+ EXPECT_TRUE(f == r);
+}
+
+#endif // LIBC_TYPES_HAS_INT128
+
+TEST(LlvmLibcUIntClassTest, OtherWordTypeTests) {
+ using LL_UInt96 = BigInt<96, false, uint32_t>;
+
+ LL_UInt96 a(1);
+
+ ASSERT_EQ(static_cast<int>(a), 1);
+ a = (a << 32) + 2;
+ ASSERT_EQ(static_cast<int>(a), 2);
+ ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(0x1'0000'0002));
+ a = (a << 32) + 3;
+ ASSERT_EQ(static_cast<int>(a), 3);
+ ASSERT_EQ(static_cast<int>(a >> 32), 2);
+ ASSERT_EQ(static_cast<int>(a >> 64), 1);
+}
} // namespace LIBC_NAMESPACE
diff --git a/test/src/compiler/stack_chk_guard_test.cpp b/test/src/compiler/stack_chk_guard_test.cpp
index 427e20c2ac50..6b71e155fa3e 100644
--- a/test/src/compiler/stack_chk_guard_test.cpp
+++ b/test/src/compiler/stack_chk_guard_test.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm-libc-macros/signal-macros.h"
+#include "include/llvm-libc-macros/signal-macros.h"
#include "src/__support/macros/sanitizer.h"
#include "src/compiler/__stack_chk_fail.h"
#include "src/string/memset.h"
diff --git a/test/src/dirent/dirent_test.cpp b/test/src/dirent/dirent_test.cpp
index e2e0399673be..41f522a6a75f 100644
--- a/test/src/dirent/dirent_test.cpp
+++ b/test/src/dirent/dirent_test.cpp
@@ -55,17 +55,17 @@ TEST(LlvmLibcDirentTest, SimpleOpenAndRead) {
}
TEST(LlvmLibcDirentTest, OpenNonExistentDir) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
::DIR *dir = LIBC_NAMESPACE::opendir("___xyz123__.non_existent__");
ASSERT_TRUE(dir == nullptr);
ASSERT_ERRNO_EQ(ENOENT);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
TEST(LlvmLibcDirentTest, OpenFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
::DIR *dir = LIBC_NAMESPACE::opendir("testdata/file1.txt");
ASSERT_TRUE(dir == nullptr);
ASSERT_ERRNO_EQ(ENOTDIR);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/errno/errno_test.cpp b/test/src/errno/errno_test.cpp
index 33185c2bcf6f..b0db22a85f3b 100644
--- a/test/src/errno/errno_test.cpp
+++ b/test/src/errno/errno_test.cpp
@@ -11,6 +11,6 @@
TEST(LlvmLibcErrnoTest, Basic) {
int test_val = 123;
- libc_errno = test_val;
- ASSERT_EQ(test_val, libc_errno);
+ LIBC_NAMESPACE::libc_errno = test_val;
+ ASSERT_ERRNO_EQ(test_val);
}
diff --git a/test/src/math/CeilTest.h b/test/src/math/CeilTest.h
index 5ea4f349d008..74cc90614dfc 100644
--- a/test/src/math/CeilTest.h
+++ b/test/src/math/CeilTest.h
@@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/CopySignTest.h b/test/src/math/CopySignTest.h
index 8b81e8d7de25..206626d66f58 100644
--- a/test/src/math/CopySignTest.h
+++ b/test/src/math/CopySignTest.h
@@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/FAbsTest.h b/test/src/math/FAbsTest.h
index bf3052afc816..942991f23be1 100644
--- a/test/src/math/FAbsTest.h
+++ b/test/src/math/FAbsTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -47,3 +50,5 @@ public:
using LlvmLibcFAbsTest = FAbsTest<T>; \
TEST_F(LlvmLibcFAbsTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcFAbsTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
diff --git a/test/src/math/FDimTest.h b/test/src/math/FDimTest.h
index e00b4fd5c42e..df8de91b4298 100644
--- a/test/src/math/FDimTest.h
+++ b/test/src/math/FDimTest.h
@@ -6,11 +6,11 @@
//
//===---------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
template <typename T>
class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
@@ -18,7 +18,6 @@ public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/FMaxTest.h b/test/src/math/FMaxTest.h
index edc46ae5bb0f..2c7dc3dc13ec 100644
--- a/test/src/math/FMaxTest.h
+++ b/test/src/math/FMaxTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -83,3 +86,5 @@ public:
TEST_F(LlvmLibcFMaxTest, NegInfArg) { testNegInfArg(&func); } \
TEST_F(LlvmLibcFMaxTest, BothZero) { testBothZero(&func); } \
TEST_F(LlvmLibcFMaxTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
diff --git a/test/src/math/FMinTest.h b/test/src/math/FMinTest.h
index 5ff583604ebc..a986d5240d0d 100644
--- a/test/src/math/FMinTest.h
+++ b/test/src/math/FMinTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -83,3 +86,5 @@ public:
TEST_F(LlvmLibcFMinTest, NegInfArg) { testNegInfArg(&func); } \
TEST_F(LlvmLibcFMinTest, BothZero) { testBothZero(&func); } \
TEST_F(LlvmLibcFMinTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
diff --git a/test/src/math/FModTest.h b/test/src/math/FModTest.h
index 2b1442923268..96ad299258a1 100644
--- a/test/src/math/FModTest.h
+++ b/test/src/math/FModTest.h
@@ -14,7 +14,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
#define TEST_SPECIAL(x, y, expected, dom_err, expected_exception) \
EXPECT_FP_EQ(expected, f(x, y)); \
diff --git a/test/src/math/FloorTest.h b/test/src/math/FloorTest.h
index 5e459ebd4928..21ae291e61bc 100644
--- a/test/src/math/FloorTest.h
+++ b/test/src/math/FloorTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -82,3 +85,5 @@ public:
TEST_F(LlvmLibcFloorTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcFloorTest, Fractions) { testFractions(&func); } \
TEST_F(LlvmLibcFloorTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
diff --git a/test/src/math/FmaTest.h b/test/src/math/FmaTest.h
index 34c582c18242..0c93ec858a12 100644
--- a/test/src/math/FmaTest.h
+++ b/test/src/math/FmaTest.h
@@ -23,7 +23,6 @@ private:
using Func = T (*)(T, T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T min_subnormal = FPBits::min_subnormal(Sign::POS).get_val();
const T min_normal = FPBits::min_normal(Sign::POS).get_val();
diff --git a/test/src/math/FrexpTest.h b/test/src/math/FrexpTest.h
index f3a64ce4aac3..f971b45628f0 100644
--- a/test/src/math/FrexpTest.h
+++ b/test/src/math/FrexpTest.h
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/HypotTest.h b/test/src/math/HypotTest.h
index 8f84024a6ee1..df69965d5dbc 100644
--- a/test/src/math/HypotTest.h
+++ b/test/src/math/HypotTest.h
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -23,7 +23,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
private:
using Func = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
+
using StorageType = typename FPBits::StorageType;
const T nan = FPBits::quiet_nan().get_val();
const T inf = FPBits::inf().get_val();
diff --git a/test/src/math/ILogbTest.h b/test/src/math/ILogbTest.h
index 3e2db33e2c05..ad47b9bb3961 100644
--- a/test/src/math/ILogbTest.h
+++ b/test/src/math/ILogbTest.h
@@ -9,11 +9,11 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_ILOGBTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_ILOGBTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
public:
@@ -24,7 +24,7 @@ public:
template <typename T>
void test_special_numbers(typename ILogbFunc<T>::Func func) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
+
EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val()));
EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val()));
EXPECT_EQ(FP_ILOGBNAN, func(FPBits::quiet_nan().get_val()));
diff --git a/test/src/math/LdExpTest.h b/test/src/math/LdExpTest.h
index fe84b5f4c192..8bfd022973b4 100644
--- a/test/src/math/LdExpTest.h
+++ b/test/src/math/LdExpTest.h
@@ -15,7 +15,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
#include <stdint.h>
template <typename T>
@@ -23,7 +23,6 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/LogbTest.h b/test/src/math/LogbTest.h
index d64c5c44e428..3859b56582e5 100644
--- a/test/src/math/LogbTest.h
+++ b/test/src/math/LogbTest.h
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/ModfTest.h b/test/src/math/ModfTest.h
index a7e5e8810611..84e26db49695 100644
--- a/test/src/math/ModfTest.h
+++ b/test/src/math/ModfTest.h
@@ -12,7 +12,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/NextAfterTest.h b/test/src/math/NextAfterTest.h
index 2f1450a16fd1..05803fb45ee2 100644
--- a/test/src/math/NextAfterTest.h
+++ b/test/src/math/NextAfterTest.h
@@ -9,19 +9,18 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
template <typename T>
class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/RIntTest.h b/test/src/math/RIntTest.h
index 3b16b902bcf5..301655c64ed3 100644
--- a/test/src/math/RIntTest.h
+++ b/test/src/math/RIntTest.h
@@ -15,8 +15,8 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include <fenv.h>
-#include <math.h>
#include <stdio.h>
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -32,7 +32,6 @@ public:
private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/RandUtils.h b/test/src/math/RandUtils.h
index 05236ead2ace..fecbd8eaabf2 100644
--- a/test/src/math/RandUtils.h
+++ b/test/src/math/RandUtils.h
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_RANDUTILS_H
+#define LLVM_LIBC_TEST_SRC_MATH_RANDUTILS_H
+
namespace LIBC_NAMESPACE {
namespace testutils {
@@ -14,3 +17,5 @@ int rand();
} // namespace testutils
} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_RANDUTILS_H
diff --git a/test/src/math/RemQuoTest.h b/test/src/math/RemQuoTest.h
index 7b3011d23055..1cb8cdbe81a2 100644
--- a/test/src/math/RemQuoTest.h
+++ b/test/src/math/RemQuoTest.h
@@ -9,12 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -22,7 +22,6 @@ template <typename T>
class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/RoundEvenTest.h b/test/src/math/RoundEvenTest.h
new file mode 100644
index 000000000000..db7263a39c0f
--- /dev/null
+++ b/test/src/math/RoundEvenTest.h
@@ -0,0 +1,92 @@
+//===-- Utility class to test roundeven[f|l] --------------------*- 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_TEST_SRC_MATH_ROUNDEVENTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#include "include/llvm-libc-macros/math-macros.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+template <typename T>
+class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*RoundEvenFunc)(T);
+
+ void testSpecialNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(zero, func(zero));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+ EXPECT_FP_EQ(inf, func(inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+ EXPECT_FP_EQ(aNaN, func(aNaN));
+ }
+
+ void testRoundedNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0)));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+ }
+
+ void testFractions(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5)));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115)));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715)));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.75)));
+ EXPECT_FP_EQ(T(11.0), func(T(10.65)));
+ EXPECT_FP_EQ(T(-11.0), func(T(-10.65)));
+ EXPECT_FP_EQ(T(1233.0), func(T(1233.25)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1233.50)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1233.75)));
+ EXPECT_FP_EQ(T(-1233.0), func(T(-1233.25)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1233.50)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1233.75)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.50)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.50)));
+ }
+
+ void testRange(RoundEvenFunc func) {
+ constexpr StorageType COUNT = 100'000;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ T x = FPBits(v).get_val();
+ if (isnan(x) || isinf(x))
+ continue;
+
+ ASSERT_MPFR_MATCH(mpfr::Operation::RoundEven, x, func(x), 0.0);
+ }
+ }
+};
+
+#define LIST_ROUNDEVEN_TESTS(T, func) \
+ using LlvmLibcRoundEvenTest = RoundEvenTest<T>; \
+ TEST_F(LlvmLibcRoundEvenTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, RoundedNubmers) { testRoundedNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, Fractions) { testFractions(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
diff --git a/test/src/math/RoundTest.h b/test/src/math/RoundTest.h
index 4860464be908..17da00f869d3 100644
--- a/test/src/math/RoundTest.h
+++ b/test/src/math/RoundTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -82,3 +85,5 @@ public:
TEST_F(LlvmLibcRoundTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcRoundTest, Fractions) { testFractions(&func); } \
TEST_F(LlvmLibcRoundTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
diff --git a/test/src/math/RoundToIntegerTest.h b/test/src/math/RoundToIntegerTest.h
index 5239528c9246..d2fabd0b4c9c 100644
--- a/test/src/math/RoundToIntegerTest.h
+++ b/test/src/math/RoundToIntegerTest.h
@@ -15,8 +15,8 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include <errno.h>
-#include <math.h>
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -31,7 +31,6 @@ public:
private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const F zero = FPBits::zero().get_val();
const F neg_zero = FPBits::zero(Sign::NEG).get_val();
@@ -51,7 +50,7 @@ private:
void test_one_input(RoundToIntegerFunc func, F input, I expected,
bool expectError) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
ASSERT_EQ(func(input), expected);
diff --git a/test/src/math/SqrtTest.h b/test/src/math/SqrtTest.h
index 75eb411810f5..9811b2767ee3 100644
--- a/test/src/math/SqrtTest.h
+++ b/test/src/math/SqrtTest.h
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/test/src/math/TruncTest.h b/test/src/math/TruncTest.h
index 0d99363526e8..c3a89dbb837b 100644
--- a/test/src/math/TruncTest.h
+++ b/test/src/math/TruncTest.h
@@ -6,11 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -82,3 +85,5 @@ public:
TEST_F(LlvmLibcTruncTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcTruncTest, Fractions) { testFractions(&func); } \
TEST_F(LlvmLibcTruncTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
diff --git a/test/src/math/acosf_test.cpp b/test/src/math/acosf_test.cpp
index 81f697c315a2..6f8321bd7182 100644
--- a/test/src/math/acosf_test.cpp
+++ b/test/src/math/acosf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/acosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAcosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/acoshf_test.cpp b/test/src/math/acoshf_test.cpp
index 6d43105c83c2..41d1166fb430 100644
--- a/test/src/math/acoshf_test.cpp
+++ b/test/src/math/acoshf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/acoshf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcAcoshfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/asinf_test.cpp b/test/src/math/asinf_test.cpp
index 77ac2bc216f7..4e36f03f4895 100644
--- a/test/src/math/asinf_test.cpp
+++ b/test/src/math/asinf_test.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/asinf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -23,7 +23,7 @@ using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcAsinfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/asinhf_test.cpp b/test/src/math/asinhf_test.cpp
index 9b925bf254a9..9a3bfbed1068 100644
--- a/test/src/math/asinhf_test.cpp
+++ b/test/src/math/asinhf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/asinhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ using LlvmLibcAsinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcAsinhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinhf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/atan2f_test.cpp b/test/src/math/atan2f_test.cpp
new file mode 100644
index 000000000000..343e7601b039
--- /dev/null
+++ b/test/src/math/atan2f_test.cpp
@@ -0,0 +1,133 @@
+//===-- Unittests for atan2f ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "include/llvm-libc-macros/math-macros.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/atan2f.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+using LIBC_NAMESPACE::testing::tlog;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAtan2fTest, TrickyInputs) {
+ constexpr int N = 17;
+ mpfr::BinaryInput<float> INPUTS[N] = {
+ {0x1.0cb3a4p+20f, 0x1.4ebacp+22f}, {0x1.12215p+1f, 0x1.4fabfcp+22f},
+ {-0x1.13baaep+41f, 0x1.5bd22ep+23f}, {0x1.1ff7dcp+41f, 0x1.aec0a6p+23f},
+ {0x1.2bc794p+23f, 0x1.0bc0c6p+23f}, {0x1.2fba3ap+42f, 0x1.f99456p+23f},
+ {0x1.5ea1f8p+27f, 0x1.f2a1aep+23f}, {0x1.7a931p+44f, 0x1.352ac4p+22f},
+ {0x1.8802bcp+21f, 0x1.8f130ap+23f}, {0x1.658ef8p+17f, 0x1.3c00f4p+22f},
+ {0x1.69fb0cp+21f, 0x1.39e4c4p+23f}, {0x1.8eb24cp+11f, 0x1.36518p+23f},
+ {0x1.9e7ebp+30f, 0x1.d80522p+23f}, {0x1.b4bdeep+19f, 0x1.c19b4p+23f},
+ {0x1.bc201p+43f, 0x1.617346p+23f}, {0x1.c96c3cp+20f, 0x1.c01d1ep+23f},
+ {0x1.781fcp+28f, 0x1.dcb3cap+23f},
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = INPUTS[i].x;
+ float y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan2, INPUTS[i],
+ LIBC_NAMESPACE::atan2f(x, y), 0.5);
+ INPUTS[i].x = -INPUTS[i].x;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan2, INPUTS[i],
+ LIBC_NAMESPACE::atan2f(-x, y), 0.5);
+ INPUTS[i].y = -INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan2, INPUTS[i],
+ LIBC_NAMESPACE::atan2f(-x, -y), 0.5);
+ INPUTS[i].x = -INPUTS[i].x;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan2, INPUTS[i],
+ LIBC_NAMESPACE::atan2f(x, -y), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcAtan2fTest, InFloatRange) {
+ constexpr uint32_t X_COUNT = 1'23;
+ constexpr uint32_t X_START = FPBits(0.25f).uintval();
+ constexpr uint32_t X_STOP = FPBits(4.0f).uintval();
+ constexpr uint32_t X_STEP = (X_STOP - X_START) / X_COUNT;
+
+ constexpr uint32_t Y_COUNT = 1'37;
+ constexpr uint32_t Y_START = FPBits(0.25f).uintval();
+ constexpr uint32_t Y_STOP = FPBits(4.0f).uintval();
+ constexpr uint32_t Y_STEP = (Y_STOP - Y_START) / Y_COUNT;
+
+ auto test = [&](mpfr::RoundingMode rounding_mode) {
+ mpfr::ForceRoundingMode __r(rounding_mode);
+ if (!__r.success)
+ return;
+
+ uint64_t fails = 0;
+ uint64_t finite_count = 0;
+ uint64_t total_count = 0;
+ float failed_x, failed_y, failed_r = 0.0;
+ double tol = 0.5;
+
+ for (uint32_t i = 0, v = X_START; i <= X_COUNT; ++i, v += X_STEP) {
+ float x = FPBits(v).get_val();
+ if (isnan(x) || isinf(x) || x < 0.0)
+ continue;
+
+ for (uint32_t j = 0, w = Y_START; j <= Y_COUNT; ++j, w += Y_STEP) {
+ float y = FPBits(w).get_val();
+ if (isnan(y) || isinf(y))
+ continue;
+
+ LIBC_NAMESPACE::libc_errno = 0;
+ float result = LIBC_NAMESPACE::atan2f(x, y);
+ ++total_count;
+ if (isnan(result) || isinf(result))
+ continue;
+
+ ++finite_count;
+ mpfr::BinaryInput<float> inputs{x, y};
+
+ if (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Atan2, inputs,
+ result, 0.5, rounding_mode)) {
+ ++fails;
+ while (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+ mpfr::Operation::Atan2, inputs, result, tol, rounding_mode)) {
+ failed_x = x;
+ failed_y = y;
+ failed_r = result;
+
+ if (tol > 1000.0)
+ break;
+
+ tol *= 2.0;
+ }
+ }
+ }
+ }
+ if (fails || (finite_count < total_count)) {
+ tlog << " Atan2f failed: " << fails << "/" << finite_count << "/"
+ << total_count << " tests.\n"
+ << " Max ULPs is at most: " << static_cast<uint64_t>(tol) << ".\n";
+ }
+ if (fails) {
+ mpfr::BinaryInput<float> inputs{failed_x, failed_y};
+ EXPECT_MPFR_MATCH(mpfr::Operation::Atan2, inputs, failed_r, 0.5,
+ rounding_mode);
+ }
+ };
+
+ tlog << " Test Rounding To Nearest...\n";
+ test(mpfr::RoundingMode::Nearest);
+
+ tlog << " Test Rounding Downward...\n";
+ test(mpfr::RoundingMode::Downward);
+
+ tlog << " Test Rounding Upward...\n";
+ test(mpfr::RoundingMode::Upward);
+
+ tlog << " Test Rounding Toward Zero...\n";
+ test(mpfr::RoundingMode::TowardZero);
+}
diff --git a/test/src/math/atanf_test.cpp b/test/src/math/atanf_test.cpp
index b5d30fbd5679..58b0eadd63f8 100644
--- a/test/src/math/atanf_test.cpp
+++ b/test/src/math/atanf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/atanf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
EXPECT_FP_EXCEPTION(0);
@@ -53,8 +53,18 @@ TEST_F(LlvmLibcAtanfTest, InFloatRange) {
// For small values, tanh(x) is x.
TEST_F(LlvmLibcAtanfTest, SpecialValues) {
- uint32_t val_arr[] = {0x3d8d6b23U, 0x3feefcfbU, 0xbd8d6b23U,
- 0xbfeefcfbU, 0x7F800000U, 0xFF800000U};
+ uint32_t val_arr[] = {
+ 0x3d8d6b23U, // x = 0x1.1ad646p-4f
+ 0x3dbb6ac7U, // x = 0x1.76d58ep-4f
+ 0x3feefcfbU, // x = 0x1.ddf9f6p+0f
+ 0x3ffe2ec1U, // x = 0x1.fc5d82p+0f
+ 0xbd8d6b23U, // x = -0x1.1ad646p-4f
+ 0xbdbb6ac7U, // x = -0x1.76d58ep-4f
+ 0xbfeefcfbU, // x = -0x1.ddf9f6p+0f
+ 0xbffe2ec1U, // x = -0x1.fc5d82p+0
+ 0x7F800000U, // x = +Inf
+ 0xFF800000U, // x = -Inf
+ };
for (uint32_t v : val_arr) {
float x = FPBits(v).get_val();
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
diff --git a/test/src/math/atanhf_test.cpp b/test/src/math/atanhf_test.cpp
index 9dea65dccd8f..c659f17d13b0 100644
--- a/test/src/math/atanhf_test.cpp
+++ b/test/src/math/atanhf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/atanhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,8 +22,8 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
- using Sign = LIBC_NAMESPACE::fputil::Sign;
- libc_errno = 0;
+
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
EXPECT_FP_EXCEPTION(0);
diff --git a/test/src/math/cos_test.cpp b/test/src/math/cos_test.cpp
index 1f55e9e9a149..6a1122997c51 100644
--- a/test/src/math/cos_test.cpp
+++ b/test/src/math/cos_test.cpp
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
using LlvmLibcCosTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/test/src/math/cosf_test.cpp b/test/src/math/cosf_test.cpp
index 9a988d76c598..8a5eb17fdcea 100644
--- a/test/src/math/cosf_test.cpp
+++ b/test/src/math/cosf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/cosf.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/Test.h"
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -24,7 +24,7 @@ using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/coshf_test.cpp b/test/src/math/coshf_test.cpp
index 843ecb8925ad..8792f56b0346 100644
--- a/test/src/math/coshf_test.cpp
+++ b/test/src/math/coshf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -23,7 +23,7 @@ using LlvmLibcCoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::coshf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -42,7 +42,7 @@ TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
}
TEST_F(LlvmLibcCoshfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::coshf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/differential_testing/ceilf_diff.cpp b/test/src/math/differential_testing/ceilf_diff.cpp
deleted file mode 100644
index 7c0bb1e95a03..000000000000
--- a/test/src/math/differential_testing/ceilf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for ceilf----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/ceilf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::ceilf, ::ceilf,
- "ceilf_diff.log")
diff --git a/test/src/math/differential_testing/cosf_diff.cpp b/test/src/math/differential_testing/cosf_diff.cpp
deleted file mode 100644
index ee3102384a8e..000000000000
--- a/test/src/math/differential_testing/cosf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for cosf ----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/cosf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::cosf, ::cosf,
- "cosf_diff.log")
diff --git a/test/src/math/differential_testing/exp2f_diff.cpp b/test/src/math/differential_testing/exp2f_diff.cpp
deleted file mode 100644
index 545c6de320fc..000000000000
--- a/test/src/math/differential_testing/exp2f_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for exp2f----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/exp2f.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::exp2f, ::exp2f,
- "exp2f_diff.log")
diff --git a/test/src/math/differential_testing/expf_diff.cpp b/test/src/math/differential_testing/expf_diff.cpp
deleted file mode 100644
index 7c2e90744bc9..000000000000
--- a/test/src/math/differential_testing/expf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/expf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::expf, ::expf,
- "expf_diff.log")
diff --git a/test/src/math/differential_testing/expm1f_diff.cpp b/test/src/math/differential_testing/expm1f_diff.cpp
deleted file mode 100644
index 3cbd8a99690f..000000000000
--- a/test/src/math/differential_testing/expm1f_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for expm1f --------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/expm1f.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::expm1f, ::expm1f,
- "expm1f_diff.log")
diff --git a/test/src/math/differential_testing/fabsf_diff.cpp b/test/src/math/differential_testing/fabsf_diff.cpp
deleted file mode 100644
index 9bf9eff888fb..000000000000
--- a/test/src/math/differential_testing/fabsf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for fabsf----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/fabsf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::fabsf, ::fabsf,
- "fabsf_diff.log")
diff --git a/test/src/math/differential_testing/floorf_diff.cpp b/test/src/math/differential_testing/floorf_diff.cpp
deleted file mode 100644
index 6d72927b5010..000000000000
--- a/test/src/math/differential_testing/floorf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for floorf---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/floorf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::floorf, ::floorf,
- "floorf_diff.log")
diff --git a/test/src/math/differential_testing/hypot_diff.cpp b/test/src/math/differential_testing/hypot_diff.cpp
deleted file mode 100644
index c61e589bdb2d..000000000000
--- a/test/src/math/differential_testing/hypot_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for hypot ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "BinaryOpSingleOutputDiff.h"
-
-#include "src/math/hypot.h"
-
-#include <math.h>
-
-BINARY_OP_SINGLE_OUTPUT_DIFF(double, LIBC_NAMESPACE::hypot, ::hypot,
- "hypot_diff.log")
diff --git a/test/src/math/differential_testing/hypotf_diff.cpp b/test/src/math/differential_testing/hypotf_diff.cpp
deleted file mode 100644
index d1c70fc2b6ed..000000000000
--- a/test/src/math/differential_testing/hypotf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for hypotf --------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "BinaryOpSingleOutputDiff.h"
-
-#include "src/math/hypotf.h"
-
-#include <math.h>
-
-BINARY_OP_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::hypotf, ::hypotf,
- "hypotf_diff.log")
diff --git a/test/src/math/differential_testing/log2f_diff.cpp b/test/src/math/differential_testing/log2f_diff.cpp
deleted file mode 100644
index aef431dce487..000000000000
--- a/test/src/math/differential_testing/log2f_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for log2f ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/log2f.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::log2f, ::log2f,
- "log2f_diff.log")
diff --git a/test/src/math/differential_testing/logbf_diff.cpp b/test/src/math/differential_testing/logbf_diff.cpp
deleted file mode 100644
index 37441eb40a4d..000000000000
--- a/test/src/math/differential_testing/logbf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for logbf----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/logbf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::logbf, ::logbf,
- "logbf_diff.log")
diff --git a/test/src/math/differential_testing/logf_diff.cpp b/test/src/math/differential_testing/logf_diff.cpp
deleted file mode 100644
index 4ed1307f7120..000000000000
--- a/test/src/math/differential_testing/logf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/logf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::logf, ::logf,
- "logf_diff.log")
diff --git a/test/src/math/differential_testing/nearbyintf_diff.cpp b/test/src/math/differential_testing/nearbyintf_diff.cpp
deleted file mode 100644
index 14200116883d..000000000000
--- a/test/src/math/differential_testing/nearbyintf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for nearbyintf-----------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/nearbyintf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::nearbyintf, ::nearbyintf,
- "nearbyintf_diff.log")
diff --git a/test/src/math/differential_testing/rintf_diff.cpp b/test/src/math/differential_testing/rintf_diff.cpp
deleted file mode 100644
index e60f66085e5d..000000000000
--- a/test/src/math/differential_testing/rintf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for rintf----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/rintf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::rintf, ::rintf,
- "rintf_diff.log")
diff --git a/test/src/math/differential_testing/roundf_diff.cpp b/test/src/math/differential_testing/roundf_diff.cpp
deleted file mode 100644
index e1401a01af35..000000000000
--- a/test/src/math/differential_testing/roundf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for roundf---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/roundf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::roundf, ::roundf,
- "roundf_diff.log")
diff --git a/test/src/math/differential_testing/sinf_diff.cpp b/test/src/math/differential_testing/sinf_diff.cpp
deleted file mode 100644
index cb4557e6796b..000000000000
--- a/test/src/math/differential_testing/sinf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for sinf ----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/sinf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::sinf, ::sinf,
- "sinf_diff.log")
diff --git a/test/src/math/differential_testing/sqrtf_diff.cpp b/test/src/math/differential_testing/sqrtf_diff.cpp
deleted file mode 100644
index 22ddeaac9caf..000000000000
--- a/test/src/math/differential_testing/sqrtf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for sqrtf----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/sqrtf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::sqrtf, ::sqrtf,
- "sqrtf_diff.log")
diff --git a/test/src/math/differential_testing/truncf_diff.cpp b/test/src/math/differential_testing/truncf_diff.cpp
deleted file mode 100644
index 7f6ac4e6a926..000000000000
--- a/test/src/math/differential_testing/truncf_diff.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- Differential test for truncf---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "SingleInputSingleOutputDiff.h"
-
-#include "src/math/truncf.h"
-
-#include <math.h>
-
-SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::truncf, ::truncf,
- "truncf_diff.log")
diff --git a/test/src/math/erff_test.cpp b/test/src/math/erff_test.cpp
index 8ebde4ec24fb..1e43c206aef0 100644
--- a/test/src/math/erff_test.cpp
+++ b/test/src/math/erff_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/erff.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/exhaustive/atanf_test.cpp b/test/src/math/exhaustive/atanf_test.cpp
index 508c288b050c..6f23231d4267 100644
--- a/test/src/math/exhaustive/atanf_test.cpp
+++ b/test/src/math/exhaustive/atanf_test.cpp
@@ -25,7 +25,7 @@ TEST_F(LlvmLibcAtanfExhaustiveTest, PostiveRange) {
}
// Range: [-Inf, 0];
-static constexpr uint32_t NEG_START = 0xb000'0000U;
+static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;
TEST_F(LlvmLibcAtanfExhaustiveTest, NegativeRange) {
diff --git a/test/src/math/exhaustive/exp2m1f_test.cpp b/test/src/math/exhaustive/exp2m1f_test.cpp
new file mode 100644
index 000000000000..2111024cb5c0
--- /dev/null
+++ b/test/src/math/exhaustive/exp2m1f_test.cpp
@@ -0,0 +1,33 @@
+//===-- Exhaustive test for exp2m1f ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/exp2m1f.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+using LlvmLibcExp2m1fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Exp2m1,
+ LIBC_NAMESPACE::exp2m1f>;
+
+// Range: [0, Inf];
+static constexpr uint32_t POS_START = 0x0000'0000U;
+static constexpr uint32_t POS_STOP = 0x7f80'0000U;
+
+TEST_F(LlvmLibcExp2m1fExhaustiveTest, PostiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP);
+}
+
+// Range: [-Inf, 0];
+static constexpr uint32_t NEG_START = 0x8000'0000U;
+static constexpr uint32_t NEG_STOP = 0xff80'0000U;
+
+TEST_F(LlvmLibcExp2m1fExhaustiveTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP);
+}
diff --git a/test/src/math/exhaustive/fmod_generic_impl_test.cpp b/test/src/math/exhaustive/fmod_generic_impl_test.cpp
index b47d24c54869..c7aec5b7bc21 100644
--- a/test/src/math/exhaustive/fmod_generic_impl_test.cpp
+++ b/test/src/math/exhaustive/fmod_generic_impl_test.cpp
@@ -6,54 +6,55 @@
//
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h" // ldexp
#include "src/__support/FPUtil/generic/FMod.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include <array>
-#include <limits>
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T, bool InverseMultiplication>
class LlvmLibcFModTest : public LIBC_NAMESPACE::testing::Test {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+ using U = typename FPBits::StorageType;
using DivisionHelper = LIBC_NAMESPACE::cpp::conditional_t<
InverseMultiplication,
- LIBC_NAMESPACE::fputil::generic::FModDivisionInvMultHelper<T>,
- LIBC_NAMESPACE::fputil::generic::FModDivisionSimpleHelper<T>>;
+ LIBC_NAMESPACE::fputil::generic::FModDivisionInvMultHelper<U>,
+ LIBC_NAMESPACE::fputil::generic::FModDivisionSimpleHelper<U>>;
- static constexpr std::array<T, 11> test_bases = {
+ static constexpr std::array<T, 11> TEST_BASES = {
T(0.0),
T(1.0),
T(3.0),
T(27.0),
T(11.0 / 8.0),
T(2.764443),
- T(1.0) - std::numeric_limits<T>::epsilon(),
- T(1.0) + std::numeric_limits<T>::epsilon(),
- T(M_PI),
- T(M_SQRT2),
- T(M_E)};
+ T(1.0) - T(0x1.0p-23) - T(0x1.0p-52) - T(0x1.0p-112),
+ T(1.0) + T(0x1.0p-23) + T(0x1.0p-52) + T(0x1.0p-112),
+ T(3.14159265),
+ T(1.41421356),
+ T(2.71828183)};
public:
void testExtensive() {
- using FMod = LIBC_NAMESPACE::fputil::generic::FMod<
- T, LIBC_NAMESPACE::fputil::generic::FModFastMathWrapper<T>,
- DivisionHelper>;
- using nl = std::numeric_limits<T>;
- int min2 = nl::min_exponent - nl::digits - 5;
- int max2 = nl::max_exponent + 3;
- for (T by : test_bases) {
+ using FMod = LIBC_NAMESPACE::fputil::generic::FMod<T, U, DivisionHelper>;
+ int min2 = -(FPBits::MAX_BIASED_EXPONENT + FPBits::SIG_LEN) / 2;
+ int max2 = 3 + FPBits::MAX_BIASED_EXPONENT / 2;
+ for (T by : TEST_BASES) {
for (int iy = min2; iy < max2; iy++) {
- T y = by * std::ldexp(2, iy);
- if (y == 0 || !std::isfinite(y))
+ T y = by * LIBC_NAMESPACE::fputil::ldexp(2.0, iy);
+ FPBits y_bits(y);
+ if (y_bits.is_zero() || !y_bits.is_finite())
continue;
- for (T bx : test_bases) {
+ for (T bx : TEST_BASES) {
for (int ix = min2; ix < max2; ix++) {
- T x = bx * std::ldexp(2, ix);
- if (!std::isfinite(x))
+ T x = bx * LIBC_NAMESPACE::fputil::ldexp(2.0, ix);
+ if (!FPBits(x).is_finite())
continue;
T result = FMod::eval(x, y);
mpfr::BinaryInput<T> input{x, y};
diff --git a/test/src/math/exp10_test.cpp b/test/src/math/exp10_test.cpp
index e9990b3ed8e6..778189626a61 100644
--- a/test/src/math/exp10_test.cpp
+++ b/test/src/math/exp10_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -106,7 +106,7 @@ TEST_F(LlvmLibcExp10Test, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::exp10(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/exp10f_test.cpp b/test/src/math/exp10f_test.cpp
index 0866488935c2..9d44e8f65dec 100644
--- a/test/src/math/exp10f_test.cpp
+++ b/test/src/math/exp10f_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
@@ -21,7 +21,7 @@ using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp10f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -40,7 +40,7 @@ TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExp10fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -55,7 +55,7 @@ TEST_F(LlvmLibcExp10fTest, Overflow) {
}
TEST_F(LlvmLibcExp10fTest, Underflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
0.0f, LIBC_NAMESPACE::exp10f(FPBits(0xff7fffffU).get_val()),
FE_UNDERFLOW);
@@ -97,7 +97,7 @@ TEST_F(LlvmLibcExp10fTest, TrickyInputs) {
0x41200000, // x = 10.0f
};
for (int i = 0; i < N; ++i) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float x = FPBits(INPUTS[i]).get_val();
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
LIBC_NAMESPACE::exp10f(x), 0.5);
@@ -113,14 +113,14 @@ TEST_F(LlvmLibcExp10fTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::exp10f(x);
// If the computation resulted in an error or did not produce valid result
// in the single-precision floating point range, then ignore comparing with
// MPFR result as MPFR can still produce valid results because of its
// wider precision.
- if (isnan(result) || isinf(result) || libc_errno != 0)
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
continue;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
LIBC_NAMESPACE::exp10f(x), 0.5);
diff --git a/test/src/math/exp2_test.cpp b/test/src/math/exp2_test.cpp
index d66c9b757625..845fda5451d4 100644
--- a/test/src/math/exp2_test.cpp
+++ b/test/src/math/exp2_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -81,7 +81,7 @@ TEST_F(LlvmLibcExp2Test, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::exp2(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/exp2f_test.cpp b/test/src/math/exp2f_test.cpp
index 18607b1d0491..f63f091eab9a 100644
--- a/test/src/math/exp2f_test.cpp
+++ b/test/src/math/exp2f_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
#include "src/errno/libc_errno.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ using LlvmLibcExp2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp2f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -41,7 +41,7 @@ TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExp2fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::exp2f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -72,7 +72,7 @@ TEST_F(LlvmLibcExp2fTest, TrickyInputs) {
0xc3150000U, /*-0x1.2ap+7f*/
};
for (int i = 0; i < N; ++i) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float x = FPBits(INPUTS[i]).get_val();
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
LIBC_NAMESPACE::exp2f(x), 0.5);
@@ -81,7 +81,7 @@ TEST_F(LlvmLibcExp2fTest, TrickyInputs) {
}
TEST_F(LlvmLibcExp2fTest, Underflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
0.0f, LIBC_NAMESPACE::exp2f(FPBits(0xff7fffffU).get_val()), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -109,14 +109,14 @@ TEST_F(LlvmLibcExp2fTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::exp2f(x);
// If the computation resulted in an error or did not produce valid result
// in the single-precision floating point range, then ignore comparing with
// MPFR result as MPFR can still produce valid results because of its
// wider precision.
- if (isnan(result) || isinf(result) || libc_errno != 0)
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
continue;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
LIBC_NAMESPACE::exp2f(x), 0.5);
diff --git a/test/src/math/exp2m1f_test.cpp b/test/src/math/exp2m1f_test.cpp
new file mode 100644
index 000000000000..a0f0da868117
--- /dev/null
+++ b/test/src/math/exp2m1f_test.cpp
@@ -0,0 +1,66 @@
+//===-- Unittests for exp2m1f ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "include/llvm-libc-macros/math-macros.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/exp2m1f.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#include <stdint.h>
+
+using LlvmLibcExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcExp2m1fTest, TrickyInputs) {
+ constexpr LIBC_NAMESPACE::cpp::array<float, 10> INPUTS = {
+ // EXP2M1F_EXCEPTS_LO
+ 0x1.36dc8ep-36,
+ 0x1.224936p-19,
+ 0x1.d16d2p-20,
+ 0x1.17949ep-14,
+ -0x1.9c3e1ep-38,
+ -0x1.4d89b4p-32,
+ -0x1.a6eac4p-10,
+ -0x1.e7526ep-6,
+ // EXP2M1F_EXCEPTS_HI
+ 0x1.16a972p-1,
+ -0x1.9f12acp-5,
+ };
+
+ for (float x : INPUTS) {
+ LIBC_NAMESPACE::libc_errno = 0;
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2m1, x,
+ LIBC_NAMESPACE::exp2m1f(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcExp2m1fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = UINT32_MAX / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ if (isnan(x) || isinf(x))
+ continue;
+ LIBC_NAMESPACE::libc_errno = 0;
+ float result = LIBC_NAMESPACE::exp2m1f(x);
+
+ // If the computation resulted in an error or did not produce valid result
+ // in the single-precision floating point range, then ignore comparing with
+ // MPFR result as MPFR can still produce valid results because of its
+ // wider precision.
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
+ continue;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2m1, x,
+ LIBC_NAMESPACE::exp2m1f(x), 0.5);
+ }
+}
diff --git a/test/src/math/exp_test.cpp b/test/src/math/exp_test.cpp
index 454107f307d8..42018e608ae4 100644
--- a/test/src/math/exp_test.cpp
+++ b/test/src/math/exp_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -79,7 +79,7 @@ TEST_F(LlvmLibcExpTest, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::exp(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/expf_test.cpp b/test/src/math/expf_test.cpp
index 0ac64ceec1c7..634958bdc43e 100644
--- a/test/src/math/expf_test.cpp
+++ b/test/src/math/expf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
@@ -21,7 +21,7 @@ using LlvmLibcExpfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::expf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -40,7 +40,7 @@ TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExpfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::expf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -55,7 +55,7 @@ TEST_F(LlvmLibcExpfTest, Overflow) {
}
TEST_F(LlvmLibcExpfTest, Underflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
0.0f, LIBC_NAMESPACE::expf(FPBits(0xff7fffffU).get_val()), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -76,7 +76,7 @@ TEST_F(LlvmLibcExpfTest, Underflow) {
TEST_F(LlvmLibcExpfTest, Borderline) {
float x;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
x = FPBits(0x42affff8U).get_val();
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
LIBC_NAMESPACE::expf(x), 0.5);
@@ -110,14 +110,14 @@ TEST_F(LlvmLibcExpfTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::expf(x);
// If the computation resulted in an error or did not produce valid result
// in the single-precision floating point range, then ignore comparing with
// MPFR result as MPFR can still produce valid results because of its
// wider precision.
- if (isnan(result) || isinf(result) || libc_errno != 0)
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
continue;
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
LIBC_NAMESPACE::expf(x), 0.5);
diff --git a/test/src/math/explogxf_test.cpp b/test/src/math/explogxf_test.cpp
index 24f9f3c0f8e4..a536a9f3ab8d 100644
--- a/test/src/math/explogxf_test.cpp
+++ b/test/src/math/explogxf_test.cpp
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
#include "in_float_range_test_helper.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.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"
-#include <math.h>
using LlvmLibcExplogfTest = LIBC_NAMESPACE::testing::FPTest<float>;
@@ -22,7 +24,7 @@ constexpr int def_count = 100003;
constexpr float def_prec = 0.500001f;
auto f_normal = [](float x) -> bool {
- return !(isnan(x) || isinf(x) || fabs(x) < 2E-38);
+ return !(isnan(x) || isinf(x) || LIBC_NAMESPACE::fabs(x) < 2E-38);
};
TEST_F(LlvmLibcExplogfTest, ExpInFloatRange) {
@@ -32,8 +34,8 @@ TEST_F(LlvmLibcExplogfTest, ExpInFloatRange) {
return static_cast<float>(result.mh * r);
};
auto f_check = [](float x) -> bool {
- return !(
- (isnan(x) || isinf(x) || x < -70 || x > 70 || fabsf(x) < 0x1.0p-10));
+ return !((isnan(x) || isinf(x) || x < -70 || x > 70 ||
+ LIBC_NAMESPACE::fabsf(x) < 0x1.0p-10));
};
CHECK_DATA(0.0f, neg_inf, mpfr::Operation::Exp, fx, f_check, def_count,
def_prec);
diff --git a/test/src/math/expm1_test.cpp b/test/src/math/expm1_test.cpp
index 99ef8275eab7..198e6d5cdd8a 100644
--- a/test/src/math/expm1_test.cpp
+++ b/test/src/math/expm1_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expm1.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -75,7 +75,7 @@ TEST_F(LlvmLibcExpm1Test, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::expm1(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/expm1f_test.cpp b/test/src/math/expm1f_test.cpp
index cc820803cc30..c72815887ba8 100644
--- a/test/src/math/expm1f_test.cpp
+++ b/test/src/math/expm1f_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expm1f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
@@ -21,7 +21,7 @@ using LlvmLibcExpm1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::expm1f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -40,7 +40,7 @@ TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExpm1fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::expm1f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
@@ -55,7 +55,7 @@ TEST_F(LlvmLibcExpm1fTest, Overflow) {
}
TEST_F(LlvmLibcExpm1fTest, Underflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::expm1f(FPBits(0xff7fffffU).get_val()));
float x = FPBits(0xc2cffff8U).get_val();
@@ -70,7 +70,7 @@ TEST_F(LlvmLibcExpm1fTest, Underflow) {
TEST_F(LlvmLibcExpm1fTest, Borderline) {
float x;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
x = FPBits(0x42affff8U).get_val();
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
LIBC_NAMESPACE::expm1f(x), 0.5);
@@ -119,14 +119,14 @@ TEST_F(LlvmLibcExpm1fTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::expm1f(x);
// If the computation resulted in an error or did not produce valid result
// in the single-precision floating point range, then ignore comparing with
// MPFR result as MPFR can still produce valid results because of its
// wider precision.
- if (isnan(result) || isinf(result) || libc_errno != 0)
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
continue;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
LIBC_NAMESPACE::expm1f(x), 0.5);
diff --git a/test/src/math/fdim_test.cpp b/test/src/math/fdim_test.cpp
index 2f00a30ad1ee..6c0c3e204c5f 100644
--- a/test/src/math/fdim_test.cpp
+++ b/test/src/math/fdim_test.cpp
@@ -8,11 +8,11 @@
#include "FDimTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdim.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
using LlvmLibcFDimTest = FDimTestTemplate<double>;
diff --git a/test/src/math/fdimf_test.cpp b/test/src/math/fdimf_test.cpp
index 27511baf25b6..a74011b5a224 100644
--- a/test/src/math/fdimf_test.cpp
+++ b/test/src/math/fdimf_test.cpp
@@ -8,11 +8,11 @@
#include "FDimTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdimf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
using LlvmLibcFDimTest = FDimTestTemplate<float>;
diff --git a/test/src/math/fdiml_test.cpp b/test/src/math/fdiml_test.cpp
index 45aedb0a1cde..d3f2e68a7c1d 100644
--- a/test/src/math/fdiml_test.cpp
+++ b/test/src/math/fdiml_test.cpp
@@ -8,11 +8,11 @@
#include "FDimTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdiml.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
using LlvmLibcFDimTest = FDimTestTemplate<long double>;
diff --git a/test/src/math/ilogb_test.cpp b/test/src/math/ilogb_test.cpp
index 7011c43386e6..45756ffa3d9a 100644
--- a/test/src/math/ilogb_test.cpp
+++ b/test/src/math/ilogb_test.cpp
@@ -8,12 +8,12 @@
#include "ILogbTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogb.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogb) {
test_special_numbers<double>(&LIBC_NAMESPACE::ilogb);
diff --git a/test/src/math/ilogbf_test.cpp b/test/src/math/ilogbf_test.cpp
index dcff8eeb1518..ff19dd145a19 100644
--- a/test/src/math/ilogbf_test.cpp
+++ b/test/src/math/ilogbf_test.cpp
@@ -8,12 +8,12 @@
#include "ILogbTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbf) {
test_special_numbers<float>(&LIBC_NAMESPACE::ilogbf);
diff --git a/test/src/math/ilogbl_test.cpp b/test/src/math/ilogbl_test.cpp
index 29a221ad7f08..b2c524666994 100644
--- a/test/src/math/ilogbl_test.cpp
+++ b/test/src/math/ilogbl_test.cpp
@@ -8,12 +8,12 @@
#include "ILogbTest.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbl.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbl) {
test_special_numbers<long double>(&LIBC_NAMESPACE::ilogbl);
diff --git a/test/src/math/in_float_range_test_helper.h b/test/src/math/in_float_range_test_helper.h
index 5f345c0cf17a..35e039e74af5 100644
--- a/test/src/math/in_float_range_test_helper.h
+++ b/test/src/math/in_float_range_test_helper.h
@@ -2,8 +2,8 @@
// Created by kirill on 8/30/22.
//
-#ifndef LLVM_IN_FLOAT_RANGE_TEST_HELPER_H
-#define LLVM_IN_FLOAT_RANGE_TEST_HELPER_H
+#ifndef LLVM_LIBC_TEST_SRC_MATH_IN_FLOAT_RANGE_TEST_HELPER_H
+#define LLVM_LIBC_TEST_SRC_MATH_IN_FLOAT_RANGE_TEST_HELPER_H
#include <stdint.h>
@@ -23,4 +23,4 @@
} \
}
-#endif // LLVM_IN_FLOAT_RANGE_TEST_HELPER_H
+#endif // LLVM_LIBC_TEST_SRC_MATH_IN_FLOAT_RANGE_TEST_HELPER_H
diff --git a/test/src/math/inv_trigf_utils_test.cpp b/test/src/math/inv_trigf_utils_test.cpp
deleted file mode 100644
index 23420edcd0ca..000000000000
--- a/test/src/math/inv_trigf_utils_test.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- Unittests for supfuncf --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache 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 "in_float_range_test_helper.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/math/generic/inv_trigf_utils.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
-
-using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
-
-namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-
-constexpr int def_count = 100003;
-constexpr float def_prec = 0.500001f;
-
-auto f_normal = [](float x) -> bool { return !(isnan(x) || isinf(x)); };
-
-TEST_F(LlvmLibcAtanfTest, InPositiveRange) {
- CHECK_DATA(0.0f, inf, mpfr::Operation::Atan, LIBC_NAMESPACE::atan_eval,
- f_normal, def_count, def_prec);
-}
-
-TEST_F(LlvmLibcAtanfTest, InNegativeRange) {
- CHECK_DATA(-0.0f, neg_inf, mpfr::Operation::Atan, LIBC_NAMESPACE::atan_eval,
- f_normal, def_count, def_prec);
-}
diff --git a/test/src/math/log10_test.cpp b/test/src/math/log10_test.cpp
index de9206f2daec..dc4ac895546c 100644
--- a/test/src/math/log10_test.cpp
+++ b/test/src/math/log10_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -102,7 +102,7 @@ TEST_F(LlvmLibcLog10Test, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::log10(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/log10f_test.cpp b/test/src/math/log10f_test.cpp
index c38a5159682c..f8a137e44c35 100644
--- a/test/src/math/log10f_test.cpp
+++ b/test/src/math/log10f_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/log1p_test.cpp b/test/src/math/log1p_test.cpp
index f70c0f87560c..975fb8e05c35 100644
--- a/test/src/math/log1p_test.cpp
+++ b/test/src/math/log1p_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log1p.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -102,7 +102,7 @@ TEST_F(LlvmLibcLog1pTest, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::log1p(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/log1pf_test.cpp b/test/src/math/log1pf_test.cpp
index 37144838552c..a1108fee4819 100644
--- a/test/src/math/log1pf_test.cpp
+++ b/test/src/math/log1pf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log1pf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -76,7 +76,7 @@ TEST_F(LlvmLibcLog1pfTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
LIBC_NAMESPACE::log1pf(x), 0.5);
}
diff --git a/test/src/math/log2_test.cpp b/test/src/math/log2_test.cpp
index 65eae58b3508..876527900579 100644
--- a/test/src/math/log2_test.cpp
+++ b/test/src/math/log2_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -101,7 +101,7 @@ TEST_F(LlvmLibcLog2Test, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::log2(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/log2f_test.cpp b/test/src/math/log2f_test.cpp
index 0793bf8a0409..c05b6b93cff7 100644
--- a/test/src/math/log2f_test.cpp
+++ b/test/src/math/log2f_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
@@ -52,13 +52,13 @@ TEST_F(LlvmLibcLog2fTest, InFloatRange) {
float x = FPBits(v).get_val();
if (isnan(x) || isinf(x))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::log2f(x);
// If the computation resulted in an error or did not produce valid result
// in the single-precision floating point range, then ignore comparing with
// MPFR result as MPFR can still produce valid results because of its
// wider precision.
- if (isnan(result) || isinf(result) || libc_errno != 0)
+ if (isnan(result) || isinf(result) || LIBC_NAMESPACE::libc_errno != 0)
continue;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log2, x,
LIBC_NAMESPACE::log2f(x), 0.5);
diff --git a/test/src/math/log_test.cpp b/test/src/math/log_test.cpp
index 457117c1757a..06a0dc574be5 100644
--- a/test/src/math/log_test.cpp
+++ b/test/src/math/log_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -100,7 +100,7 @@ TEST_F(LlvmLibcLogTest, InDoubleRange) {
double x = FPBits(v).get_val();
if (isnan(x) || isinf(x) || x < 0.0)
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::log(x);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/logf_test.cpp b/test/src/math/logf_test.cpp
index 3ab67ba80782..1ab480744ba5 100644
--- a/test/src/math/logf_test.cpp
+++ b/test/src/math/logf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/logf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <stdint.h>
diff --git a/test/src/math/nextafterf128_test.cpp b/test/src/math/nextafterf128_test.cpp
new file mode 100644
index 000000000000..a8d000ff4de3
--- /dev/null
+++ b/test/src/math/nextafterf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextafterf128 ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextafterf128.h"
+
+LIST_NEXTAFTER_TESTS(float128, LIBC_NAMESPACE::nextafterf128)
diff --git a/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h b/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
index 48572e78e515..504d1be94b89 100644
--- a/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h
+++ b/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
@@ -7,14 +7,14 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/FPBits.h"
-#include "test/src/math/differential_testing/Timer.h"
+#include "test/src/math/performance_testing/Timer.h"
#include <fstream>
namespace LIBC_NAMESPACE {
namespace testing {
-template <typename T> class BinaryOpSingleOutputDiff {
+template <typename T> class BinaryOpSingleOutputPerf {
using FPBits = fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
static constexpr StorageType UIntMax =
@@ -23,40 +23,6 @@ template <typename T> class BinaryOpSingleOutputDiff {
public:
typedef T Func(T, T);
- static uint64_t run_diff_in_range(Func myFunc, Func otherFunc,
- StorageType startingBit,
- StorageType endingBit, StorageType N,
- std::ofstream &log) {
- uint64_t result = 0;
- if (endingBit < startingBit) {
- return result;
- }
-
- StorageType step = (endingBit - startingBit) / N;
- for (StorageType bitsX = startingBit, bitsY = endingBit;;
- bitsX += step, bitsY -= step) {
- T x = T(FPBits(bitsX));
- T y = T(FPBits(bitsY));
- FPBits myBits = FPBits(myFunc(x, y));
- FPBits otherBits = FPBits(otherFunc(x, y));
- if (myBits.uintval() != otherBits.uintval()) {
- result++;
- log << " Input: " << bitsX << ", " << bitsY << " (" << x << ", "
- << y << ")\n"
- << " My result: " << myBits.uintval() << " (" << myBits.get_val()
- << ")\n"
- << "Other result: " << otherBits.uintval() << " ("
- << otherBits.get_val() << ")\n"
- << '\n';
- }
-
- if (endingBit - bitsX < step) {
- break;
- }
- }
- return result;
- }
-
static void run_perf_in_range(Func myFunc, Func otherFunc,
StorageType startingBit, StorageType endingBit,
StorageType N, std::ofstream &log) {
@@ -69,8 +35,8 @@ public:
StorageType step = (endingBit - startingBit) / N;
for (StorageType bitsX = startingBit, bitsY = endingBit;;
bitsX += step, bitsY -= step) {
- T x = T(FPBits(bitsX));
- T y = T(FPBits(bitsY));
+ T x = FPBits(bitsX).get_val();
+ T y = FPBits(bitsY).get_val();
result = func(x, y);
if (endingBit - bitsX < step) {
break;
@@ -110,17 +76,17 @@ public:
log << " Performance tests with inputs in denormal range:\n";
run_perf_in_range(myFunc, otherFunc, /* startingBit= */ StorageType(0),
/* endingBit= */ FPBits::max_subnormal().uintval(),
- 1'000'001, log);
+ 10'000'001, log);
log << "\n Performance tests with inputs in normal range:\n";
run_perf_in_range(myFunc, otherFunc,
/* startingBit= */ FPBits::min_normal().uintval(),
/* endingBit= */ FPBits::max_normal().uintval(),
- 100'000'001, log);
+ 10'000'001, log);
log << "\n Performance tests with inputs in normal range with exponents "
"close to each other:\n";
run_perf_in_range(
myFunc, otherFunc, /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(),
- /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 10'000'001, log);
+ /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 1'001'001, log);
}
static void run_diff(Func myFunc, Func otherFunc, const char *logFile) {
@@ -148,16 +114,9 @@ public:
} // namespace testing
} // namespace LIBC_NAMESPACE
-#define BINARY_OP_SINGLE_OUTPUT_DIFF(T, myFunc, otherFunc, filename) \
- int main() { \
- LIBC_NAMESPACE::testing::BinaryOpSingleOutputDiff<T>::run_diff( \
- &myFunc, &otherFunc, filename); \
- return 0; \
- }
-
#define BINARY_OP_SINGLE_OUTPUT_PERF(T, myFunc, otherFunc, filename) \
int main() { \
- LIBC_NAMESPACE::testing::BinaryOpSingleOutputDiff<T>::run_perf( \
+ LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \
&myFunc, &otherFunc, filename); \
return 0; \
}
diff --git a/test/src/math/differential_testing/SingleInputSingleOutputDiff.h b/test/src/math/performance_testing/SingleInputSingleOutputPerf.h
index 5e8310e889dc..b5b38313a69c 100644
--- a/test/src/math/differential_testing/SingleInputSingleOutputDiff.h
+++ b/test/src/math/performance_testing/SingleInputSingleOutputPerf.h
@@ -7,14 +7,14 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/FPBits.h"
-#include "test/src/math/differential_testing/Timer.h"
+#include "test/src/math/performance_testing/Timer.h"
#include <fstream>
namespace LIBC_NAMESPACE {
namespace testing {
-template <typename T> class SingleInputSingleOutputDiff {
+template <typename T> class SingleInputSingleOutputPerf {
using FPBits = fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
static constexpr StorageType UIntMax =
@@ -23,40 +23,18 @@ template <typename T> class SingleInputSingleOutputDiff {
public:
typedef T Func(T);
- static void runDiff(Func myFunc, Func otherFunc, const char *logFile) {
- StorageType diffCount = 0;
- std::ofstream log(logFile);
- log << "Starting diff for values from 0 to " << UIntMax << '\n'
- << "Only differing results will be logged.\n\n";
- for (StorageType bits = 0;; ++bits) {
- T x = T(FPBits(bits));
- T myResult = myFunc(x);
- T otherResult = otherFunc(x);
- StorageType myBits = FPBits(myResult).uintval();
- StorageType otherBits = FPBits(otherResult).uintval();
- if (myBits != otherBits) {
- ++diffCount;
- log << " Input: " << bits << " (" << x << ")\n"
- << " My result: " << myBits << " (" << myResult << ")\n"
- << "Other result: " << otherBits << " (" << otherResult << ")\n"
- << '\n';
- }
- if (bits == UIntMax)
- break;
- }
- log << "Total number of differing results: " << diffCount << '\n';
- }
-
static void runPerfInRange(Func myFunc, Func otherFunc,
StorageType startingBit, StorageType endingBit,
std::ofstream &log) {
auto runner = [=](Func func) {
+ constexpr StorageType N = 10'010'001;
+ StorageType step = (endingBit - startingBit) / N;
+ if (step == 0)
+ step = 1;
volatile T result;
- for (StorageType bits = startingBit;; ++bits) {
- T x = T(FPBits(bits));
+ for (StorageType bits = startingBit; bits < endingBit; bits += step) {
+ T x = FPBits(bits).get_val();
result = func(x);
- if (bits == endingBit)
- break;
}
};
@@ -104,16 +82,9 @@ public:
} // namespace testing
} // namespace LIBC_NAMESPACE
-#define SINGLE_INPUT_SINGLE_OUTPUT_DIFF(T, myFunc, otherFunc, filename) \
- int main() { \
- LIBC_NAMESPACE::testing::SingleInputSingleOutputDiff<T>::runDiff( \
- &myFunc, &otherFunc, filename); \
- return 0; \
- }
-
#define SINGLE_INPUT_SINGLE_OUTPUT_PERF(T, myFunc, otherFunc, filename) \
int main() { \
- LIBC_NAMESPACE::testing::SingleInputSingleOutputDiff<T>::runPerf( \
+ LIBC_NAMESPACE::testing::SingleInputSingleOutputPerf<T>::runPerf( \
&myFunc, &otherFunc, filename); \
return 0; \
}
diff --git a/test/src/math/differential_testing/Timer.cpp b/test/src/math/performance_testing/Timer.cpp
index 979196ae6b83..979196ae6b83 100644
--- a/test/src/math/differential_testing/Timer.cpp
+++ b/test/src/math/performance_testing/Timer.cpp
diff --git a/test/src/math/differential_testing/Timer.h b/test/src/math/performance_testing/Timer.h
index d4acff7ba0eb..2327ede260ab 100644
--- a/test/src/math/differential_testing/Timer.h
+++ b/test/src/math/performance_testing/Timer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_TESTUTILS_TIMER_H
-#define LLVM_LIBC_UTILS_TESTUTILS_TIMER_H
+#ifndef LLVM_LIBC_TEST_SRC_MATH_PERFORMACE_TESTING_TIMER_H
+#define LLVM_LIBC_TEST_SRC_MATH_PERFORMACE_TESTING_TIMER_H
#include <stdint.h>
@@ -30,4 +30,4 @@ public:
} // namespace testing
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_UTILS_TESTUTILS_TIMER_H
+#endif // LLVM_LIBC_TEST_SRC_MATH_PERFORMANCE_TESTING_TIMER_H
diff --git a/test/src/math/differential_testing/ceilf_perf.cpp b/test/src/math/performance_testing/ceilf_perf.cpp
index c304231e0678..04e96f6fb2dc 100644
--- a/test/src/math/differential_testing/ceilf_perf.cpp
+++ b/test/src/math/performance_testing/ceilf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/ceilf.h"
diff --git a/test/src/math/differential_testing/cosf_perf.cpp b/test/src/math/performance_testing/cosf_perf.cpp
index 981a94133b80..1501b8bf2540 100644
--- a/test/src/math/differential_testing/cosf_perf.cpp
+++ b/test/src/math/performance_testing/cosf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/cosf.h"
diff --git a/test/src/math/differential_testing/exp2f_perf.cpp b/test/src/math/performance_testing/exp2f_perf.cpp
index 4aae5220e6a5..19a70ac6569a 100644
--- a/test/src/math/differential_testing/exp2f_perf.cpp
+++ b/test/src/math/performance_testing/exp2f_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/exp2f.h"
diff --git a/test/src/math/differential_testing/expf_perf.cpp b/test/src/math/performance_testing/expf_perf.cpp
index c34173b21b4f..4b743514023d 100644
--- a/test/src/math/differential_testing/expf_perf.cpp
+++ b/test/src/math/performance_testing/expf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/expf.h"
diff --git a/test/src/math/differential_testing/expm1f_perf.cpp b/test/src/math/performance_testing/expm1f_perf.cpp
index 3c25ef81d480..128ab351d86d 100644
--- a/test/src/math/differential_testing/expm1f_perf.cpp
+++ b/test/src/math/performance_testing/expm1f_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/expm1f.h"
diff --git a/test/src/math/differential_testing/fabsf_perf.cpp b/test/src/math/performance_testing/fabsf_perf.cpp
index f9f9cea72c6d..b6c6add75d23 100644
--- a/test/src/math/differential_testing/fabsf_perf.cpp
+++ b/test/src/math/performance_testing/fabsf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/fabsf.h"
diff --git a/test/src/math/differential_testing/floorf_perf.cpp b/test/src/math/performance_testing/floorf_perf.cpp
index abd1cd7885ff..0f1087b3c823 100644
--- a/test/src/math/differential_testing/floorf_perf.cpp
+++ b/test/src/math/performance_testing/floorf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/floorf.h"
diff --git a/test/src/math/differential_testing/fmod_perf.cpp b/test/src/math/performance_testing/fmod_perf.cpp
index 219ee7860a24..fa9b4c6b4128 100644
--- a/test/src/math/differential_testing/fmod_perf.cpp
+++ b/test/src/math/performance_testing/fmod_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "BinaryOpSingleOutputDiff.h"
+#include "BinaryOpSingleOutputPerf.h"
#include "src/math/fmod.h"
diff --git a/test/src/math/differential_testing/fmodf_diff.cpp b/test/src/math/performance_testing/fmodf128_perf.cpp
index 7029b1ee42cd..8165e9254dd5 100644
--- a/test/src/math/differential_testing/fmodf_diff.cpp
+++ b/test/src/math/performance_testing/fmodf128_perf.cpp
@@ -1,4 +1,4 @@
-//===-- Differential test for fmodf ---------------------------------------===//
+//===-- Differential test for fmodf128 ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,9 +8,9 @@
#include "BinaryOpSingleOutputDiff.h"
-#include "src/math/fmodf.h"
+#include "src/math/fmodf128.h"
#include <math.h>
-BINARY_OP_SINGLE_OUTPUT_DIFF(float, LIBC_NAMESPACE::fmodf, ::fmodf,
- "fmodf_diff.log")
+BINARY_OP_SINGLE_OUTPUT_PERF(float, LIBC_NAMESPACE::fmodf128, ::fmodf128,
+ "fmodf128_perf.log")
diff --git a/test/src/math/differential_testing/fmodf_perf.cpp b/test/src/math/performance_testing/fmodf_perf.cpp
index c2927bb1ea9d..f13f02e2439d 100644
--- a/test/src/math/differential_testing/fmodf_perf.cpp
+++ b/test/src/math/performance_testing/fmodf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "BinaryOpSingleOutputDiff.h"
+#include "BinaryOpSingleOutputPerf.h"
#include "src/math/fmodf.h"
diff --git a/test/src/math/differential_testing/fmod_diff.cpp b/test/src/math/performance_testing/fmodl_perf.cpp
index 026e529c6cae..aefdf2d6b42f 100644
--- a/test/src/math/differential_testing/fmod_diff.cpp
+++ b/test/src/math/performance_testing/fmodl_perf.cpp
@@ -1,4 +1,4 @@
-//===-- Differential test for fmod ----------------------------------------===//
+//===-- Differential test for fmodl ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,9 +8,9 @@
#include "BinaryOpSingleOutputDiff.h"
-#include "src/math/fmod.h"
+#include "src/math/fmodl.h"
#include <math.h>
-BINARY_OP_SINGLE_OUTPUT_DIFF(double, LIBC_NAMESPACE::fmod, ::fmod,
- "fmod_diff.log")
+BINARY_OP_SINGLE_OUTPUT_PERF(long double, LIBC_NAMESPACE::fmodl, ::fmodl,
+ "fmodl_perf.log")
diff --git a/test/src/math/differential_testing/hypot_perf.cpp b/test/src/math/performance_testing/hypot_perf.cpp
index 01a72e6fbc3d..393697b75403 100644
--- a/test/src/math/differential_testing/hypot_perf.cpp
+++ b/test/src/math/performance_testing/hypot_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "BinaryOpSingleOutputDiff.h"
+#include "BinaryOpSingleOutputPerf.h"
#include "src/math/hypot.h"
diff --git a/test/src/math/differential_testing/hypotf_perf.cpp b/test/src/math/performance_testing/hypotf_perf.cpp
index ed57b186f889..f711729377da 100644
--- a/test/src/math/differential_testing/hypotf_perf.cpp
+++ b/test/src/math/performance_testing/hypotf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "BinaryOpSingleOutputDiff.h"
+#include "BinaryOpSingleOutputPerf.h"
#include "src/math/hypotf.h"
diff --git a/test/src/math/differential_testing/log10f_perf.cpp b/test/src/math/performance_testing/log10f_perf.cpp
index 60c1161a31cf..32a31b932528 100644
--- a/test/src/math/differential_testing/log10f_perf.cpp
+++ b/test/src/math/performance_testing/log10f_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/log10f.h"
diff --git a/test/src/math/differential_testing/log1pf_perf.cpp b/test/src/math/performance_testing/log1pf_perf.cpp
index 5cd523d82184..18c168423b87 100644
--- a/test/src/math/differential_testing/log1pf_perf.cpp
+++ b/test/src/math/performance_testing/log1pf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/log1pf.h"
diff --git a/test/src/math/differential_testing/log2f_perf.cpp b/test/src/math/performance_testing/log2f_perf.cpp
index ee899394c421..c4c4dbf4d9f5 100644
--- a/test/src/math/differential_testing/log2f_perf.cpp
+++ b/test/src/math/performance_testing/log2f_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/log2f.h"
diff --git a/test/src/math/differential_testing/logbf_perf.cpp b/test/src/math/performance_testing/logbf_perf.cpp
index 89d5bd13f931..eefd64b8ae91 100644
--- a/test/src/math/differential_testing/logbf_perf.cpp
+++ b/test/src/math/performance_testing/logbf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/logbf.h"
diff --git a/test/src/math/differential_testing/logf_perf.cpp b/test/src/math/performance_testing/logf_perf.cpp
index f1b3f986bd40..53f4f50e09ef 100644
--- a/test/src/math/differential_testing/logf_perf.cpp
+++ b/test/src/math/performance_testing/logf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/logf.h"
diff --git a/test/src/math/differential_testing/nearbyintf_perf.cpp b/test/src/math/performance_testing/nearbyintf_perf.cpp
index 9c5736fb4ab0..ae708dd21324 100644
--- a/test/src/math/differential_testing/nearbyintf_perf.cpp
+++ b/test/src/math/performance_testing/nearbyintf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/nearbyintf.h"
diff --git a/test/src/math/differential_testing/rintf_perf.cpp b/test/src/math/performance_testing/rintf_perf.cpp
index 432e5da77f37..6347ac9149af 100644
--- a/test/src/math/differential_testing/rintf_perf.cpp
+++ b/test/src/math/performance_testing/rintf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/rintf.h"
diff --git a/test/src/math/differential_testing/roundf_perf.cpp b/test/src/math/performance_testing/roundf_perf.cpp
index 091c7b2b8680..36becacba07c 100644
--- a/test/src/math/differential_testing/roundf_perf.cpp
+++ b/test/src/math/performance_testing/roundf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/roundf.h"
diff --git a/test/src/math/differential_testing/sinf_perf.cpp b/test/src/math/performance_testing/sinf_perf.cpp
index 7247bca2853d..43ba60e1ef76 100644
--- a/test/src/math/differential_testing/sinf_perf.cpp
+++ b/test/src/math/performance_testing/sinf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/sinf.h"
diff --git a/test/src/math/differential_testing/sqrtf_perf.cpp b/test/src/math/performance_testing/sqrtf_perf.cpp
index 5ae586ba3126..71325518533b 100644
--- a/test/src/math/differential_testing/sqrtf_perf.cpp
+++ b/test/src/math/performance_testing/sqrtf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/sqrtf.h"
diff --git a/test/src/math/differential_testing/truncf_perf.cpp b/test/src/math/performance_testing/truncf_perf.cpp
index e07db1320fdd..ff74c6b4eb64 100644
--- a/test/src/math/differential_testing/truncf_perf.cpp
+++ b/test/src/math/performance_testing/truncf_perf.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SingleInputSingleOutputDiff.h"
+#include "SingleInputSingleOutputPerf.h"
#include "src/math/truncf.h"
diff --git a/test/src/math/powf_test.cpp b/test/src/math/powf_test.cpp
index 608bd85bbf0c..cf674ecf8f99 100644
--- a/test/src/math/powf_test.cpp
+++ b/test/src/math/powf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/powf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -72,7 +72,7 @@ TEST_F(LlvmLibcPowfTest, InFloatRange) {
if (isnan(y) || isinf(y))
continue;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::powf(x, y);
++cc;
if (isnan(result) || isinf(result))
diff --git a/test/src/math/roundeven_test.cpp b/test/src/math/roundeven_test.cpp
new file mode 100644
index 000000000000..cd1a7bf2429f
--- /dev/null
+++ b/test/src/math/roundeven_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundeven -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundeven.h"
+
+LIST_ROUNDEVEN_TESTS(double, LIBC_NAMESPACE::roundeven)
diff --git a/test/src/math/roundevenf_test.cpp b/test/src/math/roundevenf_test.cpp
new file mode 100644
index 000000000000..68dff9b3eca9
--- /dev/null
+++ b/test/src/math/roundevenf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundevenf ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundevenf.h"
+
+LIST_ROUNDEVEN_TESTS(float, LIBC_NAMESPACE::roundevenf)
diff --git a/test/src/math/roundevenl_test.cpp b/test/src/math/roundevenl_test.cpp
new file mode 100644
index 000000000000..f4031bd65ec2
--- /dev/null
+++ b/test/src/math/roundevenl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundevenl ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundevenl.h"
+
+LIST_ROUNDEVEN_TESTS(long double, LIBC_NAMESPACE::roundevenl)
diff --git a/test/src/math/sin_test.cpp b/test/src/math/sin_test.cpp
index 69981ed22ee6..fa1c5370c30f 100644
--- a/test/src/math/sin_test.cpp
+++ b/test/src/math/sin_test.cpp
@@ -12,7 +12,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
using LlvmLibcSinTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/test/src/math/sincosf_test.cpp b/test/src/math/sincosf_test.cpp
index 76fda6354f63..a7372fd53b31 100644
--- a/test/src/math/sincosf_test.cpp
+++ b/test/src/math/sincosf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/sincosf.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/Test.h"
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -25,7 +25,7 @@ using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcSinCosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float sin, cos;
LIBC_NAMESPACE::sincosf(aNaN, &sin, &cos);
diff --git a/test/src/math/sinf_test.cpp b/test/src/math/sinf_test.cpp
index 32afc4f1c60d..a3c5384e3e62 100644
--- a/test/src/math/sinf_test.cpp
+++ b/test/src/math/sinf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/sinf.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/Test.h"
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -25,7 +25,7 @@ using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcSinfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/sinhf_test.cpp b/test/src/math/sinhf_test.cpp
index 765fdc6c2bcc..bea976055dbd 100644
--- a/test/src/math/sinhf_test.cpp
+++ b/test/src/math/sinhf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -23,7 +23,7 @@ using LlvmLibcSinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcSinhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinhf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -66,7 +66,7 @@ TEST_F(LlvmLibcSinhfTest, SmallValues) {
}
TEST_F(LlvmLibcSinhfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::sinhf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/CanonicalizeTest.h b/test/src/math/smoke/CanonicalizeTest.h
new file mode 100644
index 000000000000..4361f7d8ac7a
--- /dev/null
+++ b/test/src/math/smoke/CanonicalizeTest.h
@@ -0,0 +1,209 @@
+//===-- Utility class to test canonicalize[f|l] -----------------*- 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_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/integer_literals.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "include/llvm-libc-macros/math-macros.h"
+
+#define TEST_SPECIAL(x, y, expected, expected_exception) \
+ EXPECT_EQ(expected, f(&x, &y)); \
+ EXPECT_FP_EXCEPTION(expected_exception); \
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
+
+#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, 0)
+
+using LIBC_NAMESPACE::operator""_u128;
+
+template <typename T>
+class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef int (*CanonicalizeFunc)(T *, const T *);
+
+ void testSpecialNumbers(CanonicalizeFunc f) {
+ T cx;
+
+ TEST_SPECIAL(cx, zero, 0, 0);
+ EXPECT_FP_EQ(cx, zero);
+
+ TEST_SPECIAL(cx, neg_zero, 0, 0);
+ EXPECT_FP_EQ(cx, neg_zero);
+
+ TEST_SPECIAL(cx, inf, 0, 0);
+ EXPECT_FP_EQ(cx, inf);
+
+ TEST_SPECIAL(cx, neg_inf, 0, 0);
+ EXPECT_FP_EQ(cx, neg_inf);
+
+ TEST_SPECIAL(cx, sNaN, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+ }
+
+ void testX64_80SpecialNumbers(CanonicalizeFunc f) {
+ if constexpr (LIBC_NAMESPACE::fputil::get_fp_type<T>() ==
+ LIBC_NAMESPACE::fputil::FPType::X86_Binary80) {
+ T cx;
+ // Exponent | Significand | Meaning
+ // | Bits 63-62 | Bits 61-0 |
+ // All Ones | 00 | Zero | Pseudo Infinity, Value = SNaN
+ FPBits test1(0x00000000'00007FFF'00000000'00000000_u128);
+ const T test1_val = test1.get_val();
+ TEST_SPECIAL(cx, test1_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ // Exponent | Significand | Meaning
+ // | Bits 63-62 | Bits 61-0 |
+ // All Ones | 00 | Non-Zero | Pseudo NaN, Value = SNaN
+ FPBits test2_1(0x00000000'00007FFF'00000000'00000001_u128);
+ const T test2_1_val = test2_1.get_val();
+ TEST_SPECIAL(cx, test2_1_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test2_2(0x00000000'00007FFF'00000042'70000001_u128);
+ const T test2_2_val = test2_2.get_val();
+ TEST_SPECIAL(cx, test2_2_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test2_3(0x00000000'00007FFF'00000000'08261001_u128);
+ const T test2_3_val = test2_3.get_val();
+ TEST_SPECIAL(cx, test2_3_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test2_4(0x00000000'00007FFF'00007800'08261001_u128);
+ const T test2_4_val = test2_4.get_val();
+ TEST_SPECIAL(cx, test2_4_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ // Exponent | Significand | Meaning
+ // | Bits 63-62 | Bits 61-0 |
+ // All Ones | 01 | Anything | Pseudo NaN, Value = SNaN
+ FPBits test3_1(0x00000000'00007FFF'40000000'00000000_u128);
+ const T test3_1_val = test3_1.get_val();
+ TEST_SPECIAL(cx, test3_1_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test3_2(0x00000000'00007FFF'40000042'70000001_u128);
+ const T test3_2_val = test3_2.get_val();
+ TEST_SPECIAL(cx, test3_2_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test3_3(0x00000000'00007FFF'40000000'08261001_u128);
+ const T test3_3_val = test3_3.get_val();
+ TEST_SPECIAL(cx, test3_3_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test3_4(0x00000000'00007FFF'40007800'08261001_u128);
+ const T test3_4_val = test3_4.get_val();
+ TEST_SPECIAL(cx, test3_4_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ // Exponent | Significand | Meaning
+ // | Bit 63 | Bits 62-0 |
+ // All zeroes | One | Anything | Pseudo Denormal, Value =
+ // | | | (−1)**s × m × 2**−16382
+ FPBits test4_1(0x00000000'00000000'80000000'00000000_u128);
+ const T test4_1_val = test4_1.get_val();
+ TEST_SPECIAL(cx, test4_1_val, 0, 0);
+ EXPECT_FP_EQ(
+ cx, FPBits::make_value(test4_1.get_explicit_mantissa(), 0).get_val());
+
+ FPBits test4_2(0x00000000'00000000'80000042'70000001_u128);
+ const T test4_2_val = test4_2.get_val();
+ TEST_SPECIAL(cx, test4_2_val, 0, 0);
+ EXPECT_FP_EQ(
+ cx, FPBits::make_value(test4_2.get_explicit_mantissa(), 0).get_val());
+
+ FPBits test4_3(0x00000000'00000000'80000000'08261001_u128);
+ const T test4_3_val = test4_3.get_val();
+ TEST_SPECIAL(cx, test4_3_val, 0, 0);
+ EXPECT_FP_EQ(
+ cx, FPBits::make_value(test4_3.get_explicit_mantissa(), 0).get_val());
+
+ // Exponent | Significand | Meaning
+ // | Bit 63 | Bits 62-0 |
+ // All Other | Zero | Anything | Unnormal, Value = SNaN
+ // Values | | |
+ FPBits test5_1(0x00000000'00000040'00000000'00000001_u128);
+ const T test5_1_val = test5_1.get_val();
+ TEST_SPECIAL(cx, test5_1_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test5_2(0x00000000'00000230'00000042'70000001_u128);
+ const T test5_2_val = test5_2.get_val();
+ TEST_SPECIAL(cx, test5_2_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test5_3(0x00000000'00000560'00000000'08261001_u128);
+ const T test5_3_val = test5_3.get_val();
+ TEST_SPECIAL(cx, test5_3_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test5_4(0x00000000'00000780'00000028'16000000_u128);
+ const T test5_4_val = test5_4.get_val();
+ TEST_SPECIAL(cx, test5_4_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test5_5(0x00000000'00000900'00000042'70000001_u128);
+ const T test5_5_val = test5_5.get_val();
+ TEST_SPECIAL(cx, test5_5_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+
+ FPBits test5_6(0x00000000'00000AB0'00000000'08261001_u128);
+ const T test5_6_val = test5_6.get_val();
+ TEST_SPECIAL(cx, test5_6_val, 1, FE_INVALID);
+ EXPECT_FP_EQ(cx, aNaN);
+ }
+ }
+
+ void testRegularNumbers(CanonicalizeFunc f) {
+ T cx;
+ const T test_var_1 = T(1.0);
+ TEST_REGULAR(cx, test_var_1, 0);
+ EXPECT_FP_EQ(cx, test_var_1);
+ const T test_var_2 = T(-1.0);
+ TEST_REGULAR(cx, test_var_2, 0);
+ EXPECT_FP_EQ(cx, test_var_2);
+ const T test_var_3 = T(10.0);
+ TEST_REGULAR(cx, test_var_3, 0);
+ EXPECT_FP_EQ(cx, test_var_3);
+ const T test_var_4 = T(-10.0);
+ TEST_REGULAR(cx, test_var_4, 0);
+ EXPECT_FP_EQ(cx, test_var_4);
+ const T test_var_5 = T(1234.0);
+ TEST_REGULAR(cx, test_var_5, 0);
+ EXPECT_FP_EQ(cx, test_var_5);
+ const T test_var_6 = T(-1234.0);
+ TEST_REGULAR(cx, test_var_6, 0);
+ EXPECT_FP_EQ(cx, test_var_6);
+ }
+};
+
+#define LIST_CANONICALIZE_TESTS(T, func) \
+ using LlvmLibcCanonicalizeTest = CanonicalizeTest<T>; \
+ TEST_F(LlvmLibcCanonicalizeTest, SpecialNumbers) { \
+ testSpecialNumbers(&func); \
+ } \
+ TEST_F(LlvmLibcCanonicalizeTest, RegularNubmers) { \
+ testRegularNumbers(&func); \
+ }
+
+#define X86_80_SPECIAL_CANONICALIZE_TEST(T, func) \
+ using LlvmLibcCanonicalizeTest = CanonicalizeTest<T>; \
+ TEST_F(LlvmLibcCanonicalizeTest, X64_80SpecialNumbers) { \
+ testX64_80SpecialNumbers(&func); \
+ }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
diff --git a/test/src/math/smoke/CeilTest.h b/test/src/math/smoke/CeilTest.h
index c10fd2816014..ec70258fddec 100644
--- a/test/src/math/smoke/CeilTest.h
+++ b/test/src/math/smoke/CeilTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class CeilTest : public LIBC_NAMESPACE::testing::Test {
@@ -66,3 +69,5 @@ public:
TEST_F(LlvmLibcCeilTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcCeilTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcCeilTest, Fractions) { testFractions(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
diff --git a/test/src/math/smoke/CopySignTest.h b/test/src/math/smoke/CopySignTest.h
index 1108a45ae673..70a6a419e0a0 100644
--- a/test/src/math/smoke/CopySignTest.h
+++ b/test/src/math/smoke/CopySignTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T>
class CopySignTest : public LIBC_NAMESPACE::testing::Test {
@@ -52,3 +55,5 @@ public:
using LlvmLibcCopySignTest = CopySignTest<T>; \
TEST_F(LlvmLibcCopySignTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcCopySignTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
diff --git a/test/src/math/smoke/FAbsTest.h b/test/src/math/smoke/FAbsTest.h
index 7d905baefe85..9309c2ada4a1 100644
--- a/test/src/math/smoke/FAbsTest.h
+++ b/test/src/math/smoke/FAbsTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class FAbsTest : public LIBC_NAMESPACE::testing::Test {
@@ -35,3 +38,5 @@ public:
#define LIST_FABS_TESTS(T, func) \
using LlvmLibcFAbsTest = FAbsTest<T>; \
TEST_F(LlvmLibcFAbsTest, SpecialNumbers) { testSpecialNumbers(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
diff --git a/test/src/math/smoke/FDimTest.h b/test/src/math/smoke/FDimTest.h
index e00b4fd5c42e..e557b40d90ef 100644
--- a/test/src/math/smoke/FDimTest.h
+++ b/test/src/math/smoke/FDimTest.h
@@ -10,7 +10,6 @@
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
template <typename T>
class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
@@ -18,7 +17,6 @@ public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
@@ -26,7 +24,7 @@ public:
const T neg_zero = FPBits::zero(Sign::NEG).get_val();
const T nan = FPBits::quiet_nan().get_val();
- void test_na_n_arg(FuncPtr func) {
+ void test_nan_arg(FuncPtr func) {
EXPECT_FP_EQ(nan, func(nan, inf));
EXPECT_FP_EQ(nan, func(neg_inf, nan));
EXPECT_FP_EQ(nan, func(nan, zero));
@@ -66,12 +64,15 @@ public:
constexpr StorageType STEP = STORAGE_MAX / COUNT;
for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
++i, v += STEP, w -= STEP) {
- T x = FPBits(v).get_val(), y = FPBits(w).get_val();
- if (isnan(x) || isinf(x))
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
continue;
- if (isnan(y) || isinf(y))
+ if (ybits.is_inf_or_nan())
continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+
if (x > y) {
EXPECT_FP_EQ(x - y, func(x, y));
} else {
@@ -80,3 +81,12 @@ public:
}
}
};
+
+#define LIST_FDIM_TESTS(T, func) \
+ using LlvmLibcFDimTest = FDimTestTemplate<T>; \
+ TEST_F(LlvmLibcFDimTest, NaNArg) { test_nan_arg(&func); } \
+ TEST_F(LlvmLibcFDimTest, InfArg) { test_inf_arg(&func); } \
+ TEST_F(LlvmLibcFDimTest, NegInfArg) { test_neg_inf_arg(&func); } \
+ TEST_F(LlvmLibcFDimTest, BothZero) { test_both_zero(&func); } \
+ TEST_F(LlvmLibcFDimTest, InFloatRange) { test_in_range(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/math/smoke/FMaxTest.h b/test/src/math/smoke/FMaxTest.h
index 1a376af2e0b7..b8781a85d10f 100644
--- a/test/src/math/smoke/FMaxTest.h
+++ b/test/src/math/smoke/FMaxTest.h
@@ -1,4 +1,4 @@
-//===-- Utility class to test fmin[f|l] -------------------------*- C++ -*-===//
+//===-- Utility class to test fmax[f|l] -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -80,3 +83,5 @@ public:
TEST_F(LlvmLibcFMaxTest, NegInfArg) { testNegInfArg(&func); } \
TEST_F(LlvmLibcFMaxTest, BothZero) { testBothZero(&func); } \
TEST_F(LlvmLibcFMaxTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
diff --git a/test/src/math/smoke/FMaximumMagNumTest.h b/test/src/math/smoke/FMaximumMagNumTest.h
new file mode 100644
index 000000000000..715dd4ed913f
--- /dev/null
+++ b/test/src/math/smoke/FMaximumMagNumTest.h
@@ -0,0 +1,101 @@
+//===-- Utility class to test fmaximum_mag_num[f|l] -------------*- 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_TEST_SRC_MATH_SMOKE_FMAXIMUMMAG_NUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMMAG_NUMTEST_H
+
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMaximumMagNumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMaximumMagNumFunc)(T, T);
+
+ void testNaN(FMaximumMagNumFunc func) {
+ EXPECT_FP_EQ(inf, func(aNaN, inf));
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(sNaN, inf), FE_INVALID);
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(neg_inf, sNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, aNaN)).uintval());
+ EXPECT_FP_EQ(0.0, func(aNaN, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(0.0, func(sNaN, 0.0), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(-0.0, func(-0.0, sNaN), FE_INVALID);
+ EXPECT_FP_EQ(T(-1.2345), func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.2345), func(sNaN, T(-1.2345)), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.2345), func(T(1.2345), sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(aNaN, sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, aNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, sNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, aNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, sNaN)).uintval());
+ }
+
+ void testInfArg(FMaximumMagNumFunc func) {
+ EXPECT_FP_EQ(inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(inf, func(inf, 0.0));
+ EXPECT_FP_EQ(inf, func(-0.0, inf));
+ EXPECT_FP_EQ(inf, func(inf, T(1.2345)));
+ EXPECT_FP_EQ(inf, func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMaximumMagNumFunc func) {
+ EXPECT_FP_EQ(inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(neg_inf, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(neg_inf, func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMaximumMagNumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMaximumMagNumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (LIBC_NAMESPACE::fputil::abs(x) > LIBC_NAMESPACE::fputil::abs(y)) {
+ EXPECT_FP_EQ(x, func(x, y));
+ } else {
+ EXPECT_FP_EQ(y, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMAXIMUM_MAG_NUM_TESTS(T, func) \
+ using LlvmLibcFMaximumMagNumTest = FMaximumMagNumTest<T>; \
+ TEST_F(LlvmLibcFMaximumMagNumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMaximumMagNumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumMagNumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumMagNumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMaximumMagNumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMMAG_NUMTEST_H
diff --git a/test/src/math/smoke/FMaximumMagTest.h b/test/src/math/smoke/FMaximumMagTest.h
new file mode 100644
index 000000000000..38276e0fe2fd
--- /dev/null
+++ b/test/src/math/smoke/FMaximumMagTest.h
@@ -0,0 +1,89 @@
+//===-- Utility class to test fmaximum_mag[f|l] -----------------*- 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_TEST_SRC_MATH_SMOKE_FMAXIMUM_MAGTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUM_MAGTEST_H
+
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMaximumMagTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMaximumMagFunc)(T, T);
+
+ void testNaN(FMaximumMagFunc func) {
+ EXPECT_FP_EQ(aNaN, func(aNaN, inf));
+ EXPECT_FP_EQ(aNaN, func(neg_inf, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, 0.0));
+ EXPECT_FP_EQ(aNaN, func(-0.0, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(aNaN, func(T(1.2345), aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, aNaN));
+ }
+
+ void testInfArg(FMaximumMagFunc func) {
+ EXPECT_FP_EQ(inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(inf, func(inf, 0.0));
+ EXPECT_FP_EQ(inf, func(-0.0, inf));
+ EXPECT_FP_EQ(inf, func(inf, T(1.2345)));
+ EXPECT_FP_EQ(inf, func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMaximumMagFunc func) {
+ EXPECT_FP_EQ(inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(neg_inf, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(neg_inf, func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMaximumMagFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMaximumMagFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (LIBC_NAMESPACE::fputil::abs(x) > LIBC_NAMESPACE::fputil::abs(y)) {
+ EXPECT_FP_EQ(x, func(x, y));
+ } else {
+ EXPECT_FP_EQ(y, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMAXIMUM_MAG_TESTS(T, func) \
+ using LlvmLibcFMaximumMagTest = FMaximumMagTest<T>; \
+ TEST_F(LlvmLibcFMaximumMagTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMaximumMagTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumMagTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumMagTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMaximumMagTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUM_MAGTEST_H
diff --git a/test/src/math/smoke/FMaximumNumTest.h b/test/src/math/smoke/FMaximumNumTest.h
new file mode 100644
index 000000000000..57096f6b614a
--- /dev/null
+++ b/test/src/math/smoke/FMaximumNumTest.h
@@ -0,0 +1,100 @@
+//===-- Utility class to test fmaximum_num[f|l] -----------------*- 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_TEST_SRC_MATH_SMOKE_FMAXIMUMNUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMNUMTEST_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMaximumNumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMaximumNumFunc)(T, T);
+
+ void testNaN(FMaximumNumFunc func) {
+ EXPECT_FP_EQ(inf, func(aNaN, inf));
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(sNaN, inf), FE_INVALID);
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(neg_inf, sNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, aNaN)).uintval());
+ EXPECT_FP_EQ(0.0, func(aNaN, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(0.0, func(sNaN, 0.0), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(-0.0, func(-0.0, sNaN), FE_INVALID);
+ EXPECT_FP_EQ(T(-1.2345), func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.2345), func(sNaN, T(-1.2345)), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.2345), func(T(1.2345), sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(aNaN, sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, aNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, sNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, aNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, sNaN)).uintval());
+ }
+
+ void testInfArg(FMaximumNumFunc func) {
+ EXPECT_FP_EQ(inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(inf, func(inf, 0.0));
+ EXPECT_FP_EQ(inf, func(-0.0, inf));
+ EXPECT_FP_EQ(inf, func(inf, T(1.2345)));
+ EXPECT_FP_EQ(inf, func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMaximumNumFunc func) {
+ EXPECT_FP_EQ(inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(0.0, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(T(-1.2345), func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMaximumNumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMaximumNumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (x > y) {
+ EXPECT_FP_EQ(x, func(x, y));
+ } else {
+ EXPECT_FP_EQ(y, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMAXIMUM_NUM_TESTS(T, func) \
+ using LlvmLibcFMaximumNumTest = FMaximumNumTest<T>; \
+ TEST_F(LlvmLibcFMaximumNumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMaximumNumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumNumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumNumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMaximumNumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMNUMTEST_H
diff --git a/test/src/math/smoke/FMaximumTest.h b/test/src/math/smoke/FMaximumTest.h
new file mode 100644
index 000000000000..4db8bb93baae
--- /dev/null
+++ b/test/src/math/smoke/FMaximumTest.h
@@ -0,0 +1,88 @@
+//===-- Utility class to test fmaximum[f|l] ---------------------*- 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_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMaximumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMaximumFunc)(T, T);
+
+ void testNaN(FMaximumFunc func) {
+ EXPECT_FP_EQ(aNaN, func(aNaN, inf));
+ EXPECT_FP_EQ(aNaN, func(neg_inf, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, 0.0));
+ EXPECT_FP_EQ(aNaN, func(-0.0, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(aNaN, func(T(1.2345), aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, aNaN));
+ }
+
+ void testInfArg(FMaximumFunc func) {
+ EXPECT_FP_EQ(inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(inf, func(inf, 0.0));
+ EXPECT_FP_EQ(inf, func(-0.0, inf));
+ EXPECT_FP_EQ(inf, func(inf, T(1.2345)));
+ EXPECT_FP_EQ(inf, func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMaximumFunc func) {
+ EXPECT_FP_EQ(inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(0.0, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(T(-1.2345), func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMaximumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMaximumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (x > y) {
+ EXPECT_FP_EQ(x, func(x, y));
+ } else {
+ EXPECT_FP_EQ(y, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMAXIMUM_TESTS(T, func) \
+ using LlvmLibcFMaximumTest = FMaximumTest<T>; \
+ TEST_F(LlvmLibcFMaximumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMaximumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMaximumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMaximumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
diff --git a/test/src/math/smoke/FMinTest.h b/test/src/math/smoke/FMinTest.h
index add2544424a0..b1ffe38829f4 100644
--- a/test/src/math/smoke/FMinTest.h
+++ b/test/src/math/smoke/FMinTest.h
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -80,3 +83,5 @@ public:
TEST_F(LlvmLibcFMinTest, NegInfArg) { testNegInfArg(&func); } \
TEST_F(LlvmLibcFMinTest, BothZero) { testBothZero(&func); } \
TEST_F(LlvmLibcFMinTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
diff --git a/test/src/math/smoke/FMinimumMagNumTest.h b/test/src/math/smoke/FMinimumMagNumTest.h
new file mode 100644
index 000000000000..dec8b70740ca
--- /dev/null
+++ b/test/src/math/smoke/FMinimumMagNumTest.h
@@ -0,0 +1,101 @@
+//===-- Utility class to test fminimum_mag_num[f|l] -------------*- 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_TEST_SRC_MATH_SMOKE_FMINIMUMMAG_NUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMMAG_NUMTEST_H
+
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMinimumMagNumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMinimumMagNumFunc)(T, T);
+
+ void testNaN(FMinimumMagNumFunc func) {
+ EXPECT_FP_EQ(inf, func(aNaN, inf));
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(sNaN, inf), FE_INVALID);
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(neg_inf, sNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, aNaN)).uintval());
+ EXPECT_FP_EQ(0.0, func(aNaN, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(0.0, func(sNaN, 0.0), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(-0.0, func(-0.0, sNaN), FE_INVALID);
+ EXPECT_FP_EQ(T(-1.2345), func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.2345), func(sNaN, T(-1.2345)), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.2345), func(T(1.2345), sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(aNaN, sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, aNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, sNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, aNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, sNaN)).uintval());
+ }
+
+ void testInfArg(FMinimumMagNumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(0.0, func(inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, inf));
+ EXPECT_FP_EQ(T(1.2345), func(inf, T(1.2345)));
+ EXPECT_FP_EQ(T(-1.2345), func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMinimumMagNumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(0.0, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(T(-1.2345), func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMinimumMagNumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMinimumMagNumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (LIBC_NAMESPACE::fputil::abs(x) > LIBC_NAMESPACE::fputil::abs(y)) {
+ EXPECT_FP_EQ(y, func(x, y));
+ } else {
+ EXPECT_FP_EQ(x, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMINIMUM_MAG_NUM_TESTS(T, func) \
+ using LlvmLibcFMinimumMagNumTest = FMinimumMagNumTest<T>; \
+ TEST_F(LlvmLibcFMinimumMagNumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMinimumMagNumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumMagNumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumMagNumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMinimumMagNumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMMAG_NUMTEST_H
diff --git a/test/src/math/smoke/FMinimumMagTest.h b/test/src/math/smoke/FMinimumMagTest.h
new file mode 100644
index 000000000000..b11092e5379b
--- /dev/null
+++ b/test/src/math/smoke/FMinimumMagTest.h
@@ -0,0 +1,89 @@
+//===-- Utility class to test fminimum_mag[f|l] -----------------*- 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_TEST_SRC_MATH_SMOKE_FMINIMUM_MAGTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUM_MAGTEST_H
+
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMinimumMagTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMinimumMagFunc)(T, T);
+
+ void testNaN(FMinimumMagFunc func) {
+ EXPECT_FP_EQ(aNaN, func(aNaN, inf));
+ EXPECT_FP_EQ(aNaN, func(neg_inf, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, 0.0));
+ EXPECT_FP_EQ(aNaN, func(-0.0, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(aNaN, func(T(1.2345), aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, aNaN));
+ }
+
+ void testInfArg(FMinimumMagFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(0.0, func(inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, inf));
+ EXPECT_FP_EQ(T(1.2345), func(inf, T(1.2345)));
+ EXPECT_FP_EQ(T(-1.2345), func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMinimumMagFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(0.0, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(T(-1.2345), func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMinimumMagFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMinimumMagFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (LIBC_NAMESPACE::fputil::abs(x) < LIBC_NAMESPACE::fputil::abs(y)) {
+ EXPECT_FP_EQ(x, func(x, y));
+ } else {
+ EXPECT_FP_EQ(y, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMINIMUM_MAG_TESTS(T, func) \
+ using LlvmLibcFMinimumMagTest = FMinimumMagTest<T>; \
+ TEST_F(LlvmLibcFMinimumMagTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMinimumMagTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumMagTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumMagTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMinimumMagTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUM_MAGTEST_H
diff --git a/test/src/math/smoke/FMinimumNumTest.h b/test/src/math/smoke/FMinimumNumTest.h
new file mode 100644
index 000000000000..7fcc291b4c00
--- /dev/null
+++ b/test/src/math/smoke/FMinimumNumTest.h
@@ -0,0 +1,100 @@
+//===-- Utility class to test fminimum_num[f|l] -----------------*- 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_TEST_SRC_MATH_SMOKE_FMINIMUMNUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMNUMTEST_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMinimumNumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMinimumNumFunc)(T, T);
+
+ void testNaN(FMinimumNumFunc func) {
+ EXPECT_FP_EQ(inf, func(aNaN, inf));
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(sNaN, inf), FE_INVALID);
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(neg_inf, sNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, aNaN)).uintval());
+ EXPECT_FP_EQ(0.0, func(aNaN, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(0.0, func(sNaN, 0.0), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(-0.0, func(-0.0, sNaN), FE_INVALID);
+ EXPECT_FP_EQ(T(-1.2345), func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), aNaN));
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.2345), func(sNaN, T(-1.2345)), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.2345), func(T(1.2345), sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(aNaN, sNaN), FE_INVALID);
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, aNaN), FE_INVALID);
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(aNaN, sNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, aNaN)).uintval());
+ EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(func(sNaN, sNaN)).uintval());
+ }
+
+ void testInfArg(FMinimumNumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(0.0, func(inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, inf));
+ EXPECT_FP_EQ(T(1.2345), func(inf, T(1.2345)));
+ EXPECT_FP_EQ(T(-1.2345), func(T(-1.2345), inf));
+ }
+
+ void testNegInfArg(FMinimumNumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(neg_inf, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(neg_inf, func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMinimumNumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMinimumNumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (x > y) {
+ EXPECT_FP_EQ(y, func(x, y));
+ } else {
+ EXPECT_FP_EQ(x, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMINIMUM_NUM_TESTS(T, func) \
+ using LlvmLibcFMinimumNumTest = FMinimumNumTest<T>; \
+ TEST_F(LlvmLibcFMinimumNumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMinimumNumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumNumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumNumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMinimumNumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMNUMTEST_H
diff --git a/test/src/math/smoke/FMinimumTest.h b/test/src/math/smoke/FMinimumTest.h
new file mode 100644
index 000000000000..bc04a6d99356
--- /dev/null
+++ b/test/src/math/smoke/FMinimumTest.h
@@ -0,0 +1,88 @@
+//===-- Utility class to test fminimum[f|l] ---------------------*- 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_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FMinimumTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMinimumFunc)(T, T);
+
+ void testNaN(FMinimumFunc func) {
+ EXPECT_FP_EQ(aNaN, func(aNaN, inf));
+ EXPECT_FP_EQ(aNaN, func(neg_inf, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, 0.0));
+ EXPECT_FP_EQ(aNaN, func(-0.0, aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, T(-1.2345)));
+ EXPECT_FP_EQ(aNaN, func(T(1.2345), aNaN));
+ EXPECT_FP_EQ(aNaN, func(aNaN, aNaN));
+ }
+
+ void testInfArg(FMinimumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, inf));
+ EXPECT_FP_EQ(0.0, func(inf, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, inf));
+ EXPECT_FP_EQ(T(1.2345), func(inf, T(1.2345)));
+ EXPECT_FP_EQ(T(1.2345), func(T(1.2345), inf));
+ }
+
+ void testNegInfArg(FMinimumFunc func) {
+ EXPECT_FP_EQ(neg_inf, func(inf, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, 0.0));
+ EXPECT_FP_EQ(neg_inf, func(-0.0, neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf, T(-1.2345)));
+ EXPECT_FP_EQ(neg_inf, func(T(1.2345), neg_inf));
+ }
+
+ void testBothZero(FMinimumFunc func) {
+ EXPECT_FP_EQ(0.0, func(0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, 0.0));
+ EXPECT_FP_EQ(-0.0, func(0.0, -0.0));
+ EXPECT_FP_EQ(-0.0, func(-0.0, -0.0));
+ }
+
+ void testRange(FMinimumFunc func) {
+ constexpr StorageType COUNT = 100'001;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
+ ++i, v += STEP, w -= STEP) {
+ FPBits xbits(v), ybits(w);
+ if (xbits.is_inf_or_nan())
+ continue;
+ if (ybits.is_inf_or_nan())
+ continue;
+ T x = xbits.get_val();
+ T y = ybits.get_val();
+ if ((x == 0) && (y == 0))
+ continue;
+
+ if (x > y) {
+ EXPECT_FP_EQ(y, func(x, y));
+ } else {
+ EXPECT_FP_EQ(x, func(x, y));
+ }
+ }
+ }
+};
+
+#define LIST_FMINIMUM_TESTS(T, func) \
+ using LlvmLibcFMinimumTest = FMinimumTest<T>; \
+ TEST_F(LlvmLibcFMinimumTest, NaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcFMinimumTest, InfArg) { testInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumTest, NegInfArg) { testNegInfArg(&func); } \
+ TEST_F(LlvmLibcFMinimumTest, BothZero) { testBothZero(&func); } \
+ TEST_F(LlvmLibcFMinimumTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
diff --git a/test/src/math/smoke/FModTest.h b/test/src/math/smoke/FModTest.h
index 2b1442923268..96ad299258a1 100644
--- a/test/src/math/smoke/FModTest.h
+++ b/test/src/math/smoke/FModTest.h
@@ -14,7 +14,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
#define TEST_SPECIAL(x, y, expected, dom_err, expected_exception) \
EXPECT_FP_EQ(expected, f(x, y)); \
diff --git a/test/src/math/smoke/FloorTest.h b/test/src/math/smoke/FloorTest.h
index 1c1b62c2dcda..8886e8e75183 100644
--- a/test/src/math/smoke/FloorTest.h
+++ b/test/src/math/smoke/FloorTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class FloorTest : public LIBC_NAMESPACE::testing::Test {
@@ -66,3 +69,5 @@ public:
TEST_F(LlvmLibcFloorTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcFloorTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcFloorTest, Fractions) { testFractions(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
diff --git a/test/src/math/smoke/FmaTest.h b/test/src/math/smoke/FmaTest.h
index d04f648c2d7d..c66035927d98 100644
--- a/test/src/math/smoke/FmaTest.h
+++ b/test/src/math/smoke/FmaTest.h
@@ -19,7 +19,6 @@ private:
using Func = T (*)(T, T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/smoke/FrexpTest.h b/test/src/math/smoke/FrexpTest.h
index 981872aa128e..bf99a9a559f0 100644
--- a/test/src/math/smoke/FrexpTest.h
+++ b/test/src/math/smoke/FrexpTest.h
@@ -10,81 +10,76 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
-
template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
DECLARE_SPECIAL_CONSTANTS(T)
- static constexpr StorageType HIDDEN_BIT =
- StorageType(1) << LIBC_NAMESPACE::fputil::FPBits<T>::FRACTION_LEN;
-
public:
typedef T (*FrexpFunc)(T, int *);
void testSpecialNumbers(FrexpFunc func) {
int exponent;
- ASSERT_FP_EQ(aNaN, func(aNaN, &exponent));
- ASSERT_FP_EQ(inf, func(inf, &exponent));
- ASSERT_FP_EQ(neg_inf, func(neg_inf, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent));
- ASSERT_FP_EQ(0.0, func(0.0, &exponent));
- ASSERT_EQ(exponent, 0);
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, &exponent));
+ EXPECT_EQ(exponent, 0);
- ASSERT_FP_EQ(-0.0, func(-0.0, &exponent));
- ASSERT_EQ(exponent, 0);
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0, func(-0.0, &exponent));
+ EXPECT_EQ(exponent, 0);
}
void testPowersOfTwo(FrexpFunc func) {
int exponent;
- EXPECT_FP_EQ(T(0.5), func(T(1.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(1.0), &exponent));
EXPECT_EQ(exponent, 1);
- EXPECT_FP_EQ(T(-0.5), func(T(-1.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-1.0), &exponent));
EXPECT_EQ(exponent, 1);
- EXPECT_FP_EQ(T(0.5), func(T(2.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(2.0), &exponent));
EXPECT_EQ(exponent, 2);
- EXPECT_FP_EQ(T(-0.5), func(T(-2.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-2.0), &exponent));
EXPECT_EQ(exponent, 2);
- EXPECT_FP_EQ(T(0.5), func(T(4.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(4.0), &exponent));
EXPECT_EQ(exponent, 3);
- EXPECT_FP_EQ(T(-0.5), func(T(-4.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-4.0), &exponent));
EXPECT_EQ(exponent, 3);
- EXPECT_FP_EQ(T(0.5), func(T(8.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(8.0), &exponent));
EXPECT_EQ(exponent, 4);
- EXPECT_FP_EQ(T(-0.5), func(T(-8.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-8.0), &exponent));
EXPECT_EQ(exponent, 4);
- EXPECT_FP_EQ(T(0.5), func(T(16.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(16.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(-0.5), func(T(-16.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-16.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(0.5), func(T(32.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(32.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(-0.5), func(T(-32.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-32.0), &exponent));
EXPECT_EQ(exponent, 6);
}
void testSomeIntegers(FrexpFunc func) {
int exponent;
- EXPECT_FP_EQ(T(0.75), func(T(24.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.75), func(T(24.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(-0.75), func(T(-24.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.75), func(T(-24.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(0.625), func(T(40.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.625), func(T(40.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(-0.625), func(T(-40.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.625), func(T(-40.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(0.78125), func(T(800.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.78125), func(T(800.0), &exponent));
EXPECT_EQ(exponent, 10);
- EXPECT_FP_EQ(T(-0.78125), func(T(-800.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.78125), func(T(-800.0), &exponent));
EXPECT_EQ(exponent, 10);
}
};
@@ -93,4 +88,5 @@ public:
using LlvmLibcFrexpTest = FrexpTest<T>; \
TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); } \
- TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); }
+ TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/math/smoke/FromfpTest.h b/test/src/math/smoke/FromfpTest.h
new file mode 100644
index 000000000000..d3a61baafda1
--- /dev/null
+++ b/test/src/math/smoke/FromfpTest.h
@@ -0,0 +1,528 @@
+//===-- Utility class to test different flavors of fromfp -------*- 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_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FromfpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FromfpFunc)(T, int, unsigned int);
+
+ void testSpecialNumbersNonzeroWidth(FromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(zero, func(zero, rnd, 32U));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero, rnd, 32U));
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 32U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testSpecialNumbersZeroWidth(FromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(zero, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_zero, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 0U), FE_INVALID);
+ }
+ }
+
+ void testRoundedNumbersWithinRange(FromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0), rnd, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.0), rnd, 1U));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0), rnd, 5U));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.0), rnd, 5U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0), rnd, 12U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 65U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0), rnd, 65U));
+ }
+ }
+
+ void testRoundedNumbersOutsideRange(FromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.0), rnd, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.0), rnd, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.0), rnd, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.0), rnd, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.0), rnd, 11U), FE_INVALID);
+ }
+ }
+
+ void testFractionsUpwardWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(0.5), FP_INT_UPWARD, 2U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.115), FP_INT_UPWARD, 2U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_UPWARD, 2U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.715), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.3), FP_INT_UPWARD, 3U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_UPWARD, 3U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.5), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_UPWARD, 3U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.75), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(11.0), func(T(10.32), FP_INT_UPWARD, 5U));
+ 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(1235.0), func(T(1234.38), FP_INT_UPWARD, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_UPWARD, 12U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96), FP_INT_UPWARD, 12U));
+ }
+
+ void testFractionsUpwardOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.5), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.115), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.715), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsDownwardWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.5), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.115), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.715), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.3), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.5), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.75), FP_INT_DOWNWARD, 2U));
+ EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 5U));
+ 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(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 12U));
+ EXPECT_FP_EQ(T(-1235.0), func(T(-1234.38), FP_INT_DOWNWARD, 12U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 12U));
+ EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_DOWNWARD, 12U));
+ }
+
+ void testFractionsDownwardOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsTowardZeroWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.715), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.715), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TOWARDZERO, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.5), FP_INT_TOWARDZERO, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.5), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 2U));
+ 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, 5U));
+ 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(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TOWARDZERO, 12U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96), FP_INT_TOWARDZERO, 12U));
+ }
+
+ void testFractionsTowardZeroOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFromZeroWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(0.5), FP_INT_TONEARESTFROMZERO, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.5), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_TONEARESTFROMZERO, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TONEARESTFROMZERO, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_TONEARESTFROMZERO, 3U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5), FP_INT_TONEARESTFROMZERO, 2U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 3U));
+ 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, 5U));
+ 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(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 12U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 12U));
+ EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 12U));
+ }
+
+ void testFractionsToNearestFromZeroOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.715), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.3), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), FP_INT_TONEARESTFROMZERO, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ }
+
+ void testFractionsToNearestWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_TONEAREST, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TONEAREST, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5), FP_INT_TONEAREST, 2U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEAREST, 3U));
+ 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, 5U));
+ 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(1234.0), func(T(1234.38), FP_INT_TONEAREST, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TONEAREST, 12U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 12U));
+ EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_TONEAREST, 12U));
+
+ 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));
+ EXPECT_FP_EQ(T(2.0), func(T(2.5), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-2.5), FP_INT_TONEAREST, 2U));
+ EXPECT_FP_EQ(T(3.0), func(T(2.75), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(-3.0), func(T(-2.75), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(5.0), func(T(5.3), FP_INT_TONEAREST, 4U));
+ EXPECT_FP_EQ(T(-5.0), func(T(-5.3), FP_INT_TONEAREST, 4U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.5), FP_INT_TONEAREST, 4U));
+ EXPECT_FP_EQ(T(-6.0), func(T(-5.5), FP_INT_TONEAREST, 4U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.75), FP_INT_TONEAREST, 4U));
+ EXPECT_FP_EQ(T(-6.0), func(T(-5.75), FP_INT_TONEAREST, 4U));
+ }
+
+ void testFractionsToNearestOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.715), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.3), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.3), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.5), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.5), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.75), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.75), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFallbackWithinRange(FromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ 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, 5U));
+ EXPECT_FP_EQ(T(-10.0),
+ func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U));
+ 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(1234.0),
+ func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
+ EXPECT_FP_EQ(T(-1234.0),
+ func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
+ EXPECT_FP_EQ(T(1235.0),
+ func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
+ EXPECT_FP_EQ(T(-1235.0),
+ func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
+
+ 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));
+ EXPECT_FP_EQ(T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(-2.0), func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ EXPECT_FP_EQ(T(3.0), func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(-3.0), func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(5.0), func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ EXPECT_FP_EQ(T(-5.0), func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ EXPECT_FP_EQ(T(-6.0), func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ EXPECT_FP_EQ(T(-6.0), func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
+ }
+
+ void testFractionsToNearestFallbackOutsideRange(FromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ }
+};
+
+#define LIST_FROMFP_TESTS(T, func) \
+ using LlvmLibcFromfpTest = FromfpTestTemplate<T>; \
+ TEST_F(LlvmLibcFromfpTest, SpecialNumbersNonzeroWidth) { \
+ testSpecialNumbersNonzeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, SpecialNumbersZeroWidth) { \
+ testSpecialNumbersZeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, RoundedNumbersWithinRange) { \
+ testRoundedNumbersWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, RoundedNumbersOutsideRange) { \
+ testRoundedNumbersOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsUpwardWithinRange) { \
+ testFractionsUpwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsUpwardOutsideRange) { \
+ testFractionsUpwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsDownwardWithinRange) { \
+ testFractionsDownwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsDownwardOutsideRange) { \
+ testFractionsDownwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsTowardZeroWithinRange) { \
+ testFractionsTowardZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsTowardZeroOutsideRange) { \
+ testFractionsTowardZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestFromZeroWithinRange) { \
+ testFractionsToNearestFromZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestFromZeroOutsideRange) { \
+ testFractionsToNearestFromZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestWithinRange) { \
+ testFractionsToNearestWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestOutsideRange) { \
+ testFractionsToNearestOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestFallbackWithinRange) { \
+ testFractionsToNearestFallbackWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpTest, FractionsToNearestFallbackOutsideRange) { \
+ testFractionsToNearestFallbackOutsideRange(&func); \
+ }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
diff --git a/test/src/math/smoke/FromfpxTest.h b/test/src/math/smoke/FromfpxTest.h
new file mode 100644
index 000000000000..f3a1680b05aa
--- /dev/null
+++ b/test/src/math/smoke/FromfpxTest.h
@@ -0,0 +1,690 @@
+//===-- Utility class to test different flavors of fromfpx ------*- 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_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FromfpxFunc)(T, int, unsigned int);
+
+ void testSpecialNumbersNonzeroWidth(FromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(zero, func(zero, rnd, 32U));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero, rnd, 32U));
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 32U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testSpecialNumbersZeroWidth(FromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(zero, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_zero, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 0U), FE_INVALID);
+ }
+ }
+
+ void testRoundedNumbersWithinRange(FromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0), rnd, 2U));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.0), rnd, 1U));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0), rnd, 5U));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.0), rnd, 5U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 12U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0), rnd, 12U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 65U));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0), rnd, 65U));
+ }
+ }
+
+ void testRoundedNumbersOutsideRange(FromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.0), rnd, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.0), rnd, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.0), rnd, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.0), rnd, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.0), rnd, 11U), FE_INVALID);
+ }
+ }
+
+ void testFractionsUpwardWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.5), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.115), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.715), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.715), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.3), FP_INT_UPWARD, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.3), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.5), FP_INT_UPWARD, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.5), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.75), FP_INT_UPWARD, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.75), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.32), FP_INT_UPWARD, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.32), FP_INT_UPWARD, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_UPWARD, 5U),
+ 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(1235.0), func(T(1234.38), FP_INT_UPWARD, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.38), FP_INT_UPWARD, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.96), FP_INT_UPWARD, 12U), FE_INEXACT);
+ }
+
+ void testFractionsUpwardOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.5), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.115), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.715), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_UPWARD, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsDownwardWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.5), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.115), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.715), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.715), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.3), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.5), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.5), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.75), FP_INT_DOWNWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.32), FP_INT_DOWNWARD, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 5U),
+ 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(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1235.0), func(T(-1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1235.0), func(T(-1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ }
+
+ void testFractionsDownwardOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_DOWNWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsTowardZeroWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.715), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.715), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_TOWARDZERO, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.3), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.5), FP_INT_TOWARDZERO, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.75), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_TOWARDZERO, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-10.0), func(T(-10.32), FP_INT_TOWARDZERO, 5U), 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(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.38), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.96), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ }
+
+ void testFractionsTowardZeroOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TOWARDZERO, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 11U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFromZeroWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.5), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1.0), func(T(-0.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.115), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.115), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.715), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1.0), func(T(-0.715), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(1.3), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1.0), func(T(-1.3), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.5), FP_INT_TONEARESTFROMZERO, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-1.5), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-1.75), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(10.0), func(T(10.32), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-10.0), func(T(-10.32), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1235.0), func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 12U),
+ FE_INEXACT);
+ }
+
+ void testFractionsToNearestFromZeroOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.715), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.3), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), FP_INT_TONEARESTFROMZERO, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ }
+
+ void testFractionsToNearestWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.715), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-0.715), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-1.0), func(T(-1.3), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.5), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.5), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.75), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-1.75), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_TONEAREST, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.32), FP_INT_TONEAREST, 5U),
+ 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(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), FP_INT_TONEAREST, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.38), FP_INT_TONEAREST, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 12U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1235.0), func(T(-1234.96), FP_INT_TONEAREST, 12U), FE_INEXACT);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-2.3), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.5), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-2.0), func(T(-2.5), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(3.0), func(T(2.75), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-3.0), func(T(-2.75), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(5.0), func(T(5.3), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-5.0), func(T(-5.3), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(6.0), func(T(5.5), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-6.0), func(T(-5.5), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(6.0), func(T(5.75), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-6.0), func(T(-5.75), FP_INT_TONEAREST, 4U),
+ FE_INEXACT);
+ }
+
+ void testFractionsToNearestOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(0.715), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 4U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 11U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.3), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.3), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.5), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.5), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.75), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.75), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFallbackWithinRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1.0), func(T(-0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1.0), func(T(-1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(10.0), func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-10.0), func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-11.0), func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1234.0), func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-1235.0), func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ FE_INEXACT);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-2.0), func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(3.0), func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-3.0), func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(5.0), func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-5.0), func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(6.0), func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-6.0), func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(6.0), func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-6.0), func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
+ FE_INEXACT);
+ }
+
+ void testFractionsToNearestFallbackOutsideRange(FromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ }
+};
+
+#define LIST_FROMFPX_TESTS(T, func) \
+ using LlvmLibcFromfpxTest = FromfpxTestTemplate<T>; \
+ TEST_F(LlvmLibcFromfpxTest, SpecialNumbersNonzeroWidth) { \
+ testSpecialNumbersNonzeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, SpecialNumbersZeroWidth) { \
+ testSpecialNumbersZeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, RoundedNumbersWithinRange) { \
+ testRoundedNumbersWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, RoundedNumbersOutsideRange) { \
+ testRoundedNumbersOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsUpwardWithinRange) { \
+ testFractionsUpwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsUpwardOutsideRange) { \
+ testFractionsUpwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsDownwardWithinRange) { \
+ testFractionsDownwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsDownwardOutsideRange) { \
+ testFractionsDownwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsTowardZeroWithinRange) { \
+ testFractionsTowardZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsTowardZeroOutsideRange) { \
+ testFractionsTowardZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestFromZeroWithinRange) { \
+ testFractionsToNearestFromZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestFromZeroOutsideRange) { \
+ testFractionsToNearestFromZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestWithinRange) { \
+ testFractionsToNearestWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestOutsideRange) { \
+ testFractionsToNearestOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestFallbackWithinRange) { \
+ testFractionsToNearestFallbackWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcFromfpxTest, FractionsToNearestFallbackOutsideRange) { \
+ testFractionsToNearestFallbackOutsideRange(&func); \
+ }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
diff --git a/test/src/math/smoke/HypotTest.h b/test/src/math/smoke/HypotTest.h
index 619879188a3b..80816033f28f 100644
--- a/test/src/math/smoke/HypotTest.h
+++ b/test/src/math/smoke/HypotTest.h
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T>
class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
@@ -21,7 +21,7 @@ private:
using Func = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
+
const T nan = FPBits::quiet_nan().get_val();
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/smoke/ILogbTest.h b/test/src/math/smoke/ILogbTest.h
index 3e2db33e2c05..bb5bc33b6b3a 100644
--- a/test/src/math/smoke/ILogbTest.h
+++ b/test/src/math/smoke/ILogbTest.h
@@ -13,101 +13,109 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+template <typename OutType, typename InType>
class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<InType>;
+ using StorageType = typename FPBits::StorageType;
+
public:
- template <typename T> struct ILogbFunc {
- typedef int (*Func)(T);
- };
-
- template <typename T>
- void test_special_numbers(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
- EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val()));
- EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val()));
- EXPECT_EQ(FP_ILOGBNAN, func(FPBits::quiet_nan().get_val()));
- EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::POS).get_val()));
- EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::NEG).get_val()));
+ typedef OutType (*Func)(InType);
+
+ void test_special_numbers(Func func) {
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGB0,
+ func(FPBits::zero(Sign::POS).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGB0,
+ func(FPBits::zero(Sign::NEG).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGBNAN,
+ func(FPBits::quiet_nan().get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::T_MAX,
+ func(FPBits::inf(Sign::POS).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::T_MAX,
+ func(FPBits::inf(Sign::NEG).get_val()));
}
- template <typename T>
- void test_powers_of_two(typename ILogbFunc<T>::Func func) {
- EXPECT_EQ(0, func(T(1.0)));
- EXPECT_EQ(0, func(T(-1.0)));
+ void test_powers_of_two(Func func) {
+ EXPECT_EQ(OutType(0), func(InType(1.0)));
+ EXPECT_EQ(OutType(0), func(InType(-1.0)));
- EXPECT_EQ(1, func(T(2.0)));
- EXPECT_EQ(1, func(T(-2.0)));
+ EXPECT_EQ(OutType(1), func(InType(2.0)));
+ EXPECT_EQ(OutType(1), func(InType(-2.0)));
- EXPECT_EQ(2, func(T(4.0)));
- EXPECT_EQ(2, func(T(-4.0)));
+ EXPECT_EQ(OutType(2), func(InType(4.0)));
+ EXPECT_EQ(OutType(2), func(InType(-4.0)));
- EXPECT_EQ(3, func(T(8.0)));
- EXPECT_EQ(3, func(-8.0));
+ EXPECT_EQ(OutType(3), func(InType(8.0)));
+ EXPECT_EQ(OutType(3), func(-8.0));
- EXPECT_EQ(4, func(16.0));
- EXPECT_EQ(4, func(-16.0));
+ EXPECT_EQ(OutType(4), func(16.0));
+ EXPECT_EQ(OutType(4), func(-16.0));
- EXPECT_EQ(5, func(32.0));
- EXPECT_EQ(5, func(-32.0));
+ EXPECT_EQ(OutType(5), func(32.0));
+ EXPECT_EQ(OutType(5), func(-32.0));
}
- template <typename T>
- void test_some_integers(typename ILogbFunc<T>::Func func) {
- EXPECT_EQ(1, func(T(3.0)));
- EXPECT_EQ(1, func(T(-3.0)));
+ void test_some_integers(Func func) {
+ EXPECT_EQ(OutType(1), func(InType(3.0)));
+ EXPECT_EQ(OutType(1), func(InType(-3.0)));
- EXPECT_EQ(2, func(T(7.0)));
- EXPECT_EQ(2, func(T(-7.0)));
+ EXPECT_EQ(OutType(2), func(InType(7.0)));
+ EXPECT_EQ(OutType(2), func(InType(-7.0)));
- EXPECT_EQ(3, func(T(10.0)));
- EXPECT_EQ(3, func(T(-10.0)));
+ EXPECT_EQ(OutType(3), func(InType(10.0)));
+ EXPECT_EQ(OutType(3), func(InType(-10.0)));
- EXPECT_EQ(4, func(T(31.0)));
- EXPECT_EQ(4, func(-31.0));
+ EXPECT_EQ(OutType(4), func(InType(31.0)));
+ EXPECT_EQ(OutType(4), func(-31.0));
- EXPECT_EQ(5, func(55.0));
- EXPECT_EQ(5, func(-55.0));
+ EXPECT_EQ(OutType(5), func(55.0));
+ EXPECT_EQ(OutType(5), func(-55.0));
}
- template <typename T>
- void test_subnormal_range(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using StorageType = typename FPBits::StorageType;
+ void test_subnormal_range(Func func) {
constexpr StorageType MIN_SUBNORMAL = FPBits::min_subnormal().uintval();
constexpr StorageType MAX_SUBNORMAL = FPBits::max_subnormal().uintval();
constexpr StorageType COUNT = 10'001;
constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
for (StorageType v = MIN_SUBNORMAL; v <= MAX_SUBNORMAL; v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ InType x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
- ASSERT_EQ(exponent, func(x) + 1);
+ ASSERT_EQ(static_cast<OutType>(exponent), func(x) + OutType(1));
}
}
- template <typename T>
- void test_normal_range(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using StorageType = typename FPBits::StorageType;
+ void test_normal_range(Func func) {
constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval();
constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval();
constexpr StorageType COUNT = 10'001;
constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
for (StorageType v = MIN_NORMAL; v <= MAX_NORMAL; v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ InType x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
- ASSERT_EQ(exponent, func(x) + 1);
+ ASSERT_EQ(static_cast<OutType>(exponent), func(x) + OutType(1));
}
}
};
+#define LIST_INTLOGB_TESTS(OutType, InType, Func) \
+ using LlvmLibcIntLogbTest = LlvmLibcILogbTest<OutType, InType>; \
+ TEST_F(LlvmLibcIntLogbTest, SpecialNumbers) { test_special_numbers(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, PowersOfTwo) { test_powers_of_two(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, SomeIntegers) { test_some_integers(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, SubnormalRange) { test_subnormal_range(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, NormalRange) { test_normal_range(&Func); } \
+ static_assert(true)
+
#endif // LLVM_LIBC_TEST_SRC_MATH_ILOGBTEST_H
diff --git a/test/src/math/smoke/LdExpTest.h b/test/src/math/smoke/LdExpTest.h
index fe84b5f4c192..c3e852a2a473 100644
--- a/test/src/math/smoke/LdExpTest.h
+++ b/test/src/math/smoke/LdExpTest.h
@@ -15,7 +15,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
template <typename T>
@@ -23,7 +22,6 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
@@ -163,6 +161,7 @@ public:
TEST_F(LlvmLibcLdExpTest, UnderflowToZeroOnSubnormal) { \
testUnderflowToZeroOnSubnormal(&func); \
} \
- TEST_F(LlvmLibcLdExpTest, NormalOperation) { testNormalOperation(&func); }
+ TEST_F(LlvmLibcLdExpTest, NormalOperation) { testNormalOperation(&func); } \
+ static_assert(true)
#endif // LLVM_LIBC_TEST_SRC_MATH_LDEXPTEST_H
diff --git a/test/src/math/smoke/LogbTest.h b/test/src/math/smoke/LogbTest.h
index e2698e2b7b81..01e1050b4c4f 100644
--- a/test/src/math/smoke/LogbTest.h
+++ b/test/src/math/smoke/LogbTest.h
@@ -10,8 +10,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
-
template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
DECLARE_SPECIAL_CONSTANTS(T)
@@ -72,10 +70,12 @@ public:
constexpr StorageType COUNT = 100'000;
constexpr StorageType STEP = STORAGE_MAX / COUNT;
for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0l)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ T x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
ASSERT_FP_EQ(T(exponent), func(x) + T(1.0));
diff --git a/test/src/math/smoke/ModfTest.h b/test/src/math/smoke/ModfTest.h
index a73e5ae4298f..107963665b83 100644
--- a/test/src/math/smoke/ModfTest.h
+++ b/test/src/math/smoke/ModfTest.h
@@ -11,7 +11,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class ModfTest : public LIBC_NAMESPACE::testing::Test {
@@ -84,10 +84,12 @@ public:
constexpr StorageType COUNT = 100'000;
constexpr StorageType STEP = STORAGE_MAX / COUNT;
for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == T(0.0))
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ T x = x_bits.get_val();
+
T integral;
T frac = func(x, &integral);
ASSERT_TRUE(LIBC_NAMESPACE::fputil::abs(frac) < 1.0l);
diff --git a/test/src/math/smoke/NextAfterTest.h b/test/src/math/smoke/NextAfterTest.h
index dda86eeeb6e0..403ea6bd8df6 100644
--- a/test/src/math/smoke/NextAfterTest.h
+++ b/test/src/math/smoke/NextAfterTest.h
@@ -9,13 +9,13 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception) \
ASSERT_FP_EQ(result, expected); \
@@ -32,7 +32,6 @@ template <typename T>
class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/smoke/NextDownTest.h b/test/src/math/smoke/NextDownTest.h
new file mode 100644
index 000000000000..c678ab1db1de
--- /dev/null
+++ b/test/src/math/smoke/NextDownTest.h
@@ -0,0 +1,43 @@
+//===-- Utility class to test different flavors of nextdown -----*- 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_TEST_SRC_MATH_NEXTDOWNTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class NextDownTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*NextDownFunc)(T);
+
+ void testNaN(NextDownFunc func) { ASSERT_FP_EQ(func(aNaN), aNaN); }
+
+ void testBoundaries(NextDownFunc func) {
+ ASSERT_FP_EQ(zero, func(min_denormal));
+
+ ASSERT_FP_EQ(neg_min_denormal, func(zero));
+ ASSERT_FP_EQ(neg_min_denormal, func(neg_zero));
+
+ ASSERT_FP_EQ(neg_max_normal, func(neg_max_normal));
+ ASSERT_FP_EQ(neg_inf, func(neg_inf));
+
+ ASSERT_FP_EQ(max_normal, func(inf));
+ }
+};
+
+#define LIST_NEXTDOWN_TESTS(T, func) \
+ using LlvmLibcNextDownTest = NextDownTestTemplate<T>; \
+ TEST_F(LlvmLibcNextDownTest, TestNaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcNextDownTest, TestBoundaries) { testBoundaries(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
diff --git a/test/src/math/smoke/NextTowardTest.h b/test/src/math/smoke/NextTowardTest.h
index 42a9a56aeb0a..0c2abf815c23 100644
--- a/test/src/math/smoke/NextTowardTest.h
+++ b/test/src/math/smoke/NextTowardTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTTOWARDTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_NEXTTOWARDTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
@@ -16,7 +17,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include <fenv.h>
-#include <math.h>
#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception) \
ASSERT_FP_EQ(result, expected); \
@@ -34,7 +34,6 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using ToFPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/smoke/NextUpTest.h b/test/src/math/smoke/NextUpTest.h
new file mode 100644
index 000000000000..ebbdb5c73def
--- /dev/null
+++ b/test/src/math/smoke/NextUpTest.h
@@ -0,0 +1,43 @@
+//===-- Utility class to test different flavors of nextup -------*- 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_TEST_SRC_MATH_NEXTUPTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class NextUpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*NextUpFunc)(T);
+
+ void testNaN(NextUpFunc func) { ASSERT_FP_EQ(func(aNaN), aNaN); }
+
+ void testBoundaries(NextUpFunc func) {
+ ASSERT_FP_EQ(neg_zero, func(neg_min_denormal));
+
+ ASSERT_FP_EQ(min_denormal, func(zero));
+ ASSERT_FP_EQ(min_denormal, func(neg_zero));
+
+ ASSERT_FP_EQ(max_normal, func(max_normal));
+ ASSERT_FP_EQ(inf, func(inf));
+
+ ASSERT_FP_EQ(neg_max_normal, func(neg_inf));
+ }
+};
+
+#define LIST_NEXTUP_TESTS(T, func) \
+ using LlvmLibcNextUpTest = NextUpTestTemplate<T>; \
+ TEST_F(LlvmLibcNextUpTest, TestNaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcNextUpTest, TestBoundaries) { testBoundaries(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
diff --git a/test/src/math/smoke/RIntTest.h b/test/src/math/smoke/RIntTest.h
index 233164b41247..5a283a8bc0b5 100644
--- a/test/src/math/smoke/RIntTest.h
+++ b/test/src/math/smoke/RIntTest.h
@@ -6,16 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H
-#define LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_RINTTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_RINTTEST_H
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include <fenv.h>
-#include <math.h>
#include <stdio.h>
static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
@@ -29,7 +29,6 @@ public:
private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
@@ -54,4 +53,4 @@ public:
using LlvmLibcRIntTest = RIntTestTemplate<F>; \
TEST_F(LlvmLibcRIntTest, specialNumbers) { testSpecialNumbers(&func); }
-#endif // LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_RINTTEST_H
diff --git a/test/src/math/smoke/RemQuoTest.h b/test/src/math/smoke/RemQuoTest.h
index 87551faeda9c..cf56b1d6460f 100644
--- a/test/src/math/smoke/RemQuoTest.h
+++ b/test/src/math/smoke/RemQuoTest.h
@@ -9,17 +9,16 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
template <typename T>
class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const T inf = FPBits::inf(Sign::POS).get_val();
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
diff --git a/test/src/math/smoke/RoundEvenTest.h b/test/src/math/smoke/RoundEvenTest.h
new file mode 100644
index 000000000000..107052fa0e28
--- /dev/null
+++ b/test/src/math/smoke/RoundEvenTest.h
@@ -0,0 +1,72 @@
+//===-- Utility class to test roundeven[f|l] --------------------*- 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_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "include/llvm-libc-macros/math-macros.h"
+
+template <typename T>
+class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*RoundEvenFunc)(T);
+
+ void testSpecialNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(zero, func(zero));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+ EXPECT_FP_EQ(inf, func(inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+ EXPECT_FP_EQ(aNaN, func(aNaN));
+ }
+
+ void testRoundedNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0)));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+ }
+
+ void testFractions(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5)));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115)));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.75)));
+ EXPECT_FP_EQ(T(10.0), func(T(10.50)));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.50)));
+ EXPECT_FP_EQ(T(11.0), func(T(10.65)));
+ EXPECT_FP_EQ(T(-11.0), func(T(-10.65)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.50)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.50)));
+ EXPECT_FP_EQ(T(1236.0), func(T(1235.50)));
+ EXPECT_FP_EQ(T(-1236.0), func(T(-1235.50)));
+ }
+};
+
+#define LIST_ROUNDEVEN_TESTS(T, func) \
+ using LlvmLibcRoundEvenTest = RoundEvenTest<T>; \
+ TEST_F(LlvmLibcRoundEvenTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, RoundedNubmers) { testRoundedNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, Fractions) { testFractions(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
diff --git a/test/src/math/smoke/RoundTest.h b/test/src/math/smoke/RoundTest.h
index 2e95f182ce94..8cf96f456903 100644
--- a/test/src/math/smoke/RoundTest.h
+++ b/test/src/math/smoke/RoundTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
@@ -66,3 +69,5 @@ public:
TEST_F(LlvmLibcRoundTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcRoundTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcRoundTest, Fractions) { testFractions(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
diff --git a/test/src/math/smoke/RoundToIntegerTest.h b/test/src/math/smoke/RoundToIntegerTest.h
index 1fdff23e9159..44b3f8996df5 100644
--- a/test/src/math/smoke/RoundToIntegerTest.h
+++ b/test/src/math/smoke/RoundToIntegerTest.h
@@ -6,16 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
-#define LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTOINTEGERTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTOINTEGERTEST_H
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
+#include "include/llvm-libc-macros/math-macros.h"
#include <errno.h>
-#include <math.h>
static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
FE_TONEAREST};
@@ -28,7 +28,6 @@ public:
private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>;
using StorageType = typename FPBits::StorageType;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
const F zero = FPBits::zero(Sign::POS).get_val();
const F neg_zero = FPBits::zero(Sign::NEG).get_val();
@@ -46,7 +45,7 @@ private:
void test_one_input(RoundToIntegerFunc func, F input, I expected,
bool expectError) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
ASSERT_EQ(func(input), expected);
@@ -169,4 +168,4 @@ public:
#define LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(F, I, func) \
LIST_ROUND_TO_INTEGER_TESTS_HELPER(F, I, func, true)
-#endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTOINTEGERTEST_H
diff --git a/test/src/math/smoke/SqrtTest.h b/test/src/math/smoke/SqrtTest.h
index edb6e74236e3..eea5dc1534e0 100644
--- a/test/src/math/smoke/SqrtTest.h
+++ b/test/src/math/smoke/SqrtTest.h
@@ -10,7 +10,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
diff --git a/test/src/math/smoke/TruncTest.h b/test/src/math/smoke/TruncTest.h
index 8334a7b7c0f9..5612d27fef21 100644
--- a/test/src/math/smoke/TruncTest.h
+++ b/test/src/math/smoke/TruncTest.h
@@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
+
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
template <typename T> class TruncTest : public LIBC_NAMESPACE::testing::Test {
@@ -66,3 +69,5 @@ public:
TEST_F(LlvmLibcTruncTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcTruncTest, RoundedNubmers) { testRoundedNumbers(&func); } \
TEST_F(LlvmLibcTruncTest, Fractions) { testFractions(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
diff --git a/test/src/math/smoke/UfromfpTest.h b/test/src/math/smoke/UfromfpTest.h
new file mode 100644
index 000000000000..9ad1e6dce945
--- /dev/null
+++ b/test/src/math/smoke/UfromfpTest.h
@@ -0,0 +1,462 @@
+//===-- Utility class to test different flavors of ufromfp ------*- 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_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*UfromfpFunc)(T, int, unsigned int);
+
+ void testSpecialNumbersNonzeroWidth(UfromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(zero, func(zero, rnd, 32U));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero, rnd, 32U));
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 32U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testSpecialNumbersZeroWidth(UfromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(zero, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_zero, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 0U), FE_INVALID);
+ }
+ }
+
+ void testRoundedNumbersWithinRange(UfromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0), rnd, 1U));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0), rnd, 4U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 11U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 64U));
+ }
+ }
+
+ void testRoundedNumbersOutsideRange(UfromfpFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.0), rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.0), rnd, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.0), rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.0), rnd, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.0), rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testFractionsUpwardWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(0.5), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.115), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.715), FP_INT_UPWARD, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.3), FP_INT_UPWARD, 2U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_UPWARD, 2U));
+ 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(1235.0), func(T(1234.38), FP_INT_UPWARD, 11U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 11U));
+ }
+
+ void testFractionsUpwardOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsDownwardWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.715), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_DOWNWARD, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.5), FP_INT_DOWNWARD, 1U));
+ 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(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 11U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 11U));
+ }
+
+ void testFractionsDownwardOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.5), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.115), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.715), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_DOWNWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_DOWNWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsTowardZeroWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.715), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.715), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TOWARDZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.5), FP_INT_TOWARDZERO, 1U));
+ 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(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 11U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 11U));
+ }
+
+ void testFractionsTowardZeroOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TOWARDZERO, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TOWARDZERO, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFromZeroWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(0.5), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TONEARESTFROMZERO, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_TONEARESTFROMZERO, 2U));
+ 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(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U));
+ }
+
+ void testFractionsToNearestFromZeroOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.5), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.715), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.3), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), FP_INT_TONEARESTFROMZERO, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), FP_INT_TONEARESTFROMZERO, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ }
+
+ void testFractionsToNearestWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), FP_INT_TONEAREST, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), FP_INT_TONEAREST, 2U));
+ 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(1234.0), func(T(1234.38), FP_INT_TONEAREST, 11U));
+ EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 11U));
+
+ 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));
+ EXPECT_FP_EQ(T(3.0), func(T(2.75), FP_INT_TONEAREST, 2U));
+ EXPECT_FP_EQ(T(5.0), func(T(5.3), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.5), FP_INT_TONEAREST, 3U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.75), FP_INT_TONEAREST, 3U));
+ }
+
+ void testFractionsToNearestOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.715), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.3), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFallbackWithinRange(UfromfpFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ 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(1234.0),
+ func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U));
+ EXPECT_FP_EQ(T(1235.0),
+ func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U));
+
+ 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));
+ EXPECT_FP_EQ(T(3.0), func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
+ EXPECT_FP_EQ(T(5.0), func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ EXPECT_FP_EQ(T(6.0), func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
+ }
+
+ void testFractionsToNearestFallbackOutsideRange(UfromfpFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ }
+};
+
+#define LIST_UFROMFP_TESTS(T, func) \
+ using LlvmLibcUfromfpTest = UfromfpTestTemplate<T>; \
+ TEST_F(LlvmLibcUfromfpTest, SpecialNumbersNonzeroWidth) { \
+ testSpecialNumbersNonzeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, SpecialNumbersZeroWidth) { \
+ testSpecialNumbersZeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, RoundedNumbersWithinRange) { \
+ testRoundedNumbersWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, RoundedNumbersOutsideRange) { \
+ testRoundedNumbersOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsUpwardWithinRange) { \
+ testFractionsUpwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsUpwardOutsideRange) { \
+ testFractionsUpwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsDownwardWithinRange) { \
+ testFractionsDownwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsDownwardOutsideRange) { \
+ testFractionsDownwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsTowardZeroWithinRange) { \
+ testFractionsTowardZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsTowardZeroOutsideRange) { \
+ testFractionsTowardZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestFromZeroWithinRange) { \
+ testFractionsToNearestFromZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestFromZeroOutsideRange) { \
+ testFractionsToNearestFromZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestWithinRange) { \
+ testFractionsToNearestWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestOutsideRange) { \
+ testFractionsToNearestOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestFallbackWithinRange) { \
+ testFractionsToNearestFallbackWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpTest, FractionsToNearestFallbackOutsideRange) { \
+ testFractionsToNearestFallbackOutsideRange(&func); \
+ }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
diff --git a/test/src/math/smoke/UfromfpxTest.h b/test/src/math/smoke/UfromfpxTest.h
new file mode 100644
index 000000000000..09163b8adfa5
--- /dev/null
+++ b/test/src/math/smoke/UfromfpxTest.h
@@ -0,0 +1,551 @@
+//===-- Utility class to test different flavors of ufromfpx -----*- 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_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*UfromfpxFunc)(T, int, unsigned int);
+
+ void testSpecialNumbersNonzeroWidth(UfromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(zero, func(zero, rnd, 32U));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero, rnd, 32U));
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 32U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testSpecialNumbersZeroWidth(UfromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(zero, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_zero, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(inf, rnd, 0U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(neg_inf, rnd, 0U), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(aNaN, rnd, 0U), FE_INVALID);
+ }
+ }
+
+ void testRoundedNumbersWithinRange(UfromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0), rnd, 1U));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0), rnd, 4U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 11U));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0), rnd, 64U));
+ }
+ }
+
+ void testRoundedNumbersOutsideRange(UfromfpxFunc func) {
+ for (int rnd : MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.0), rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.0), rnd, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.0), rnd, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.0), rnd, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.0), rnd, 32U), FE_INVALID);
+ }
+ }
+
+ void testFractionsUpwardWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.5), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.115), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.715), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.715), FP_INT_UPWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.3), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.5), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.75), FP_INT_UPWARD, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.32), FP_INT_UPWARD, 4U),
+ 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(1235.0), func(T(1234.38), FP_INT_UPWARD, 11U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 11U),
+ FE_INEXACT);
+ }
+
+ void testFractionsUpwardOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.3), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_UPWARD, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsDownwardWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.715), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.5), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 4U),
+ 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(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 11U), FE_INEXACT);
+ }
+
+ void testFractionsDownwardOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.5), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.115), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.715), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_DOWNWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_DOWNWARD, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsTowardZeroWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.715), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.715), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.5), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_TOWARDZERO, 4U),
+ 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(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 11U), FE_INEXACT);
+ }
+
+ void testFractionsTowardZeroOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TOWARDZERO, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TOWARDZERO, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFromZeroWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.115), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.115), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.715), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(1.3), FP_INT_TONEARESTFROMZERO, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.5), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(10.0), func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INEXACT);
+ }
+
+ void testFractionsToNearestFromZeroOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.5), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.715), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.3), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), FP_INT_TONEARESTFROMZERO, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), FP_INT_TONEARESTFROMZERO, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), FP_INT_TONEARESTFROMZERO, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ }
+
+ void testFractionsToNearestWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.5), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.5), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(0.0), func(T(0.115), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-0.0), func(T(-0.115), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(0.715), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(1.0), func(T(1.3), FP_INT_TONEAREST, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.5), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(1.75), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.32), FP_INT_TONEAREST, 4U),
+ 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(1234.0), func(T(1234.38), FP_INT_TONEAREST, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 11U), FE_INEXACT);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.5), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(3.0), func(T(2.75), FP_INT_TONEAREST, 2U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(5.0), func(T(5.3), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(6.0), func(T(5.5), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(6.0), func(T(5.75), FP_INT_TONEAREST, 3U),
+ FE_INEXACT);
+ }
+
+ void testFractionsToNearestOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-0.715), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.32), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.32), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(10.65), FP_INT_TONEAREST, 3U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.5), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.75), FP_INT_TONEAREST, 1U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-2.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.3), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.3), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.5), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.5), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(5.75), FP_INT_TONEAREST, 2U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-5.75), FP_INT_TONEAREST, 32U),
+ FE_INVALID);
+ }
+
+ void testFractionsToNearestFallbackWithinRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(0.0), func(T(0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(-0.0), func(T(-0.115), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1.0), func(T(1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(10.0), func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1234.0), func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(1235.0), func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ FE_INEXACT);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(3.0), func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(5.0), func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(6.0), func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ T(6.0), func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INEXACT);
+ }
+
+ void testFractionsToNearestFallbackOutsideRange(UfromfpxFunc func) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-0.715), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
+ FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 1U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-2.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U), FE_INVALID);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ aNaN, func(T(-5.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U), FE_INVALID);
+ }
+};
+
+#define LIST_UFROMFPX_TESTS(T, func) \
+ using LlvmLibcUfromfpxTest = UfromfpxTestTemplate<T>; \
+ TEST_F(LlvmLibcUfromfpxTest, SpecialNumbersNonzeroWidth) { \
+ testSpecialNumbersNonzeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, SpecialNumbersZeroWidth) { \
+ testSpecialNumbersZeroWidth(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, RoundedNumbersWithinRange) { \
+ testRoundedNumbersWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, RoundedNumbersOutsideRange) { \
+ testRoundedNumbersOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsUpwardWithinRange) { \
+ testFractionsUpwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsUpwardOutsideRange) { \
+ testFractionsUpwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsDownwardWithinRange) { \
+ testFractionsDownwardWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsDownwardOutsideRange) { \
+ testFractionsDownwardOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsTowardZeroWithinRange) { \
+ testFractionsTowardZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsTowardZeroOutsideRange) { \
+ testFractionsTowardZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestFromZeroWithinRange) { \
+ testFractionsToNearestFromZeroWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestFromZeroOutsideRange) { \
+ testFractionsToNearestFromZeroOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestWithinRange) { \
+ testFractionsToNearestWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestOutsideRange) { \
+ testFractionsToNearestOutsideRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestFallbackWithinRange) { \
+ testFractionsToNearestFallbackWithinRange(&func); \
+ } \
+ TEST_F(LlvmLibcUfromfpxTest, FractionsToNearestFallbackOutsideRange) { \
+ testFractionsToNearestFallbackOutsideRange(&func); \
+ }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
diff --git a/test/src/math/smoke/acosf_test.cpp b/test/src/math/smoke/acosf_test.cpp
index 2d8fba96718c..573a2c39492f 100644
--- a/test/src/math/smoke/acosf_test.cpp
+++ b/test/src/math/smoke/acosf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/acosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAcosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/acoshf_test.cpp b/test/src/math/smoke/acoshf_test.cpp
index 85c24e08ab79..f561f23eb99a 100644
--- a/test/src/math/smoke/acoshf_test.cpp
+++ b/test/src/math/smoke/acoshf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/acoshf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAcoshfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/asinf_test.cpp b/test/src/math/smoke/asinf_test.cpp
index 57bb7dcf6e84..39d25e72c143 100644
--- a/test/src/math/smoke/asinf_test.cpp
+++ b/test/src/math/smoke/asinf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/asinf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAsinfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/asinhf_test.cpp b/test/src/math/smoke/asinhf_test.cpp
index 0c6ac537ef1c..9637bfa53948 100644
--- a/test/src/math/smoke/asinhf_test.cpp
+++ b/test/src/math/smoke/asinhf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/asinhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcAsinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAsinhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinhf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/atan2f_test.cpp b/test/src/math/smoke/atan2f_test.cpp
new file mode 100644
index 000000000000..ecac36b3a8c0
--- /dev/null
+++ b/test/src/math/smoke/atan2f_test.cpp
@@ -0,0 +1,50 @@
+//===-- Unittests for atan2f ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "include/llvm-libc-macros/math-macros.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/atan2f.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+TEST_F(LlvmLibcAtan2fTest, SpecialNumbers) {
+ LIBC_NAMESPACE::libc_errno = 0;
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(1.0f, aNaN));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atan2f(zero, zero));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atan2f(-0.0f, zero));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atan2f(1.0f, inf));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atan2f(-1.0f, inf));
+ EXPECT_FP_EXCEPTION(0);
+ EXPECT_MATH_ERRNO(0);
+}
diff --git a/test/src/math/smoke/atanf_test.cpp b/test/src/math/smoke/atanf_test.cpp
index 156ce0744b0e..abd9835d38a0 100644
--- a/test/src/math/smoke/atanf_test.cpp
+++ b/test/src/math/smoke/atanf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/atanf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
diff --git a/test/src/math/smoke/atanhf_test.cpp b/test/src/math/smoke/atanhf_test.cpp
index c613f9bdf35f..590a7ab60f04 100644
--- a/test/src/math/smoke/atanhf_test.cpp
+++ b/test/src/math/smoke/atanhf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/atanhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,8 +19,8 @@
using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
- using Sign = LIBC_NAMESPACE::fputil::Sign;
- libc_errno = 0;
+
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
diff --git a/test/src/math/smoke/canonicalize_test.cpp b/test/src/math/smoke/canonicalize_test.cpp
new file mode 100644
index 000000000000..54a1ddd49ca4
--- /dev/null
+++ b/test/src/math/smoke/canonicalize_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalize ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/canonicalize.h"
+
+LIST_CANONICALIZE_TESTS(double, LIBC_NAMESPACE::canonicalize)
diff --git a/test/src/math/smoke/canonicalizef128_test.cpp b/test/src/math/smoke/canonicalizef128_test.cpp
new file mode 100644
index 000000000000..242e2331a29e
--- /dev/null
+++ b/test/src/math/smoke/canonicalizef128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalizef128 ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/canonicalizef128.h"
+
+LIST_CANONICALIZE_TESTS(float128, LIBC_NAMESPACE::canonicalizef128)
diff --git a/test/src/math/smoke/canonicalizef_test.cpp b/test/src/math/smoke/canonicalizef_test.cpp
new file mode 100644
index 000000000000..17cf3c3639a4
--- /dev/null
+++ b/test/src/math/smoke/canonicalizef_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalizef ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/canonicalizef.h"
+
+LIST_CANONICALIZE_TESTS(float, LIBC_NAMESPACE::canonicalizef)
diff --git a/test/src/math/smoke/canonicalizel_test.cpp b/test/src/math/smoke/canonicalizel_test.cpp
new file mode 100644
index 000000000000..23cb21dce84e
--- /dev/null
+++ b/test/src/math/smoke/canonicalizel_test.cpp
@@ -0,0 +1,19 @@
+//===-- Unittests for canonicalizel ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/canonicalizel.h"
+
+LIST_CANONICALIZE_TESTS(long double, LIBC_NAMESPACE::canonicalizel)
+
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+X86_80_SPECIAL_CANONICALIZE_TEST(long double, LIBC_NAMESPACE::canonicalizel)
+
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
diff --git a/test/src/math/smoke/ceilf128_test.cpp b/test/src/math/smoke/ceilf128_test.cpp
new file mode 100644
index 000000000000..f0da8258f79b
--- /dev/null
+++ b/test/src/math/smoke/ceilf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ceilf128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ceilf128.h"
+
+LIST_CEIL_TESTS(float128, LIBC_NAMESPACE::ceilf128)
diff --git a/test/src/math/smoke/cosf_test.cpp b/test/src/math/smoke/cosf_test.cpp
index c9efc791885f..62132990ed54 100644
--- a/test/src/math/smoke/cosf_test.cpp
+++ b/test/src/math/smoke/cosf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/cosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cosf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/coshf_test.cpp b/test/src/math/smoke/coshf_test.cpp
index aa224dcc156f..9d7ef505ae74 100644
--- a/test/src/math/smoke/coshf_test.cpp
+++ b/test/src/math/smoke/coshf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/coshf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -20,7 +20,7 @@
using LlvmLibcCoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::coshf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -39,7 +39,7 @@ TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
}
TEST_F(LlvmLibcCoshfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::coshf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/erff_test.cpp b/test/src/math/smoke/erff_test.cpp
index 843cc7f4c8c0..24778f8d653a 100644
--- a/test/src/math/smoke/erff_test.cpp
+++ b/test/src/math/smoke/erff_test.cpp
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/erff.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/exp10_test.cpp b/test/src/math/smoke/exp10_test.cpp
index daa7b5b48842..fffffeb4c78a 100644
--- a/test/src/math/smoke/exp10_test.cpp
+++ b/test/src/math/smoke/exp10_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/exp10f_test.cpp b/test/src/math/smoke/exp10f_test.cpp
index d242edf04fb3..c0dcc1250332 100644
--- a/test/src/math/smoke/exp10f_test.cpp
+++ b/test/src/math/smoke/exp10f_test.cpp
@@ -6,19 +6,19 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp10f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -41,7 +41,7 @@ TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExp10fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/exp2_test.cpp b/test/src/math/smoke/exp2_test.cpp
index 7bcc2a3cb6c7..d362d32f678b 100644
--- a/test/src/math/smoke/exp2_test.cpp
+++ b/test/src/math/smoke/exp2_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/exp2f_test.cpp b/test/src/math/smoke/exp2f_test.cpp
index e4e56ed23bcf..e2989a6ec4d8 100644
--- a/test/src/math/smoke/exp2f_test.cpp
+++ b/test/src/math/smoke/exp2f_test.cpp
@@ -6,20 +6,20 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
#include "src/errno/libc_errno.h"
#include "src/math/exp2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
using LlvmLibcExp2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp2f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -43,7 +43,7 @@ TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExp2fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::exp2f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/exp2m1f_test.cpp b/test/src/math/smoke/exp2m1f_test.cpp
new file mode 100644
index 000000000000..2df435385247
--- /dev/null
+++ b/test/src/math/smoke/exp2m1f_test.cpp
@@ -0,0 +1,63 @@
+//===-- Unittests for exp2m1f ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/errno/libc_errno.h"
+#include "src/math/exp2m1f.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode;
+using LIBC_NAMESPACE::fputil::testing::RoundingMode;
+
+TEST_F(LlvmLibcExp2m1fTest, SpecialNumbers) {
+ LIBC_NAMESPACE::libc_errno = 0;
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp2m1f(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::exp2m1f(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(-1.0f, LIBC_NAMESPACE::exp2m1f(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::exp2m1f(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::exp2m1f(-0.0f));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(1.0f, LIBC_NAMESPACE::exp2m1f(1.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.5f, LIBC_NAMESPACE::exp2m1f(-1.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(3.0f, LIBC_NAMESPACE::exp2m1f(2.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.75f, LIBC_NAMESPACE::exp2m1f(-2.0f));
+}
+
+TEST_F(LlvmLibcExp2m1fTest, Overflow) {
+ LIBC_NAMESPACE::libc_errno = 0;
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::exp2m1f(0x1.fffffep+127),
+ FE_OVERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::exp2m1f(128.0f),
+ FE_OVERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::exp2m1f(0x1.000002p+7),
+ FE_OVERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+}
+
+TEST_F(LlvmLibcExp2m1fTest, Underflow) {
+ LIBC_NAMESPACE::libc_errno = 0;
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(-1.0f, LIBC_NAMESPACE::exp2m1f(-0x1.fffffep+127),
+ FE_UNDERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(-1.0f, LIBC_NAMESPACE::exp2m1f(-25.0f),
+ FE_UNDERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(-1.0f, LIBC_NAMESPACE::exp2m1f(-0x1.900002p4),
+ FE_UNDERFLOW);
+ EXPECT_MATH_ERRNO(ERANGE);
+}
diff --git a/test/src/math/smoke/exp_test.cpp b/test/src/math/smoke/exp_test.cpp
index 455cb2ea1353..a2becc74f526 100644
--- a/test/src/math/smoke/exp_test.cpp
+++ b/test/src/math/smoke/exp_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/exp.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/expf_test.cpp b/test/src/math/smoke/expf_test.cpp
index 24fc35b552ca..42710c5fa404 100644
--- a/test/src/math/smoke/expf_test.cpp
+++ b/test/src/math/smoke/expf_test.cpp
@@ -6,19 +6,19 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
using LlvmLibcExpfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::expf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -37,7 +37,7 @@ TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExpfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::expf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/expm1_test.cpp b/test/src/math/smoke/expm1_test.cpp
index 4581060075e3..07963ec2d34c 100644
--- a/test/src/math/smoke/expm1_test.cpp
+++ b/test/src/math/smoke/expm1_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expm1.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/expm1f_test.cpp b/test/src/math/smoke/expm1f_test.cpp
index 3d6dae77ec00..82e0b1546350 100644
--- a/test/src/math/smoke/expm1f_test.cpp
+++ b/test/src/math/smoke/expm1f_test.cpp
@@ -6,19 +6,19 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/expm1f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
using LlvmLibcExpm1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::expm1f(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -37,7 +37,7 @@ TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
}
TEST_F(LlvmLibcExpm1fTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::expm1f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/fdim_test.cpp b/test/src/math/smoke/fdim_test.cpp
index 2f00a30ad1ee..e1c150da90af 100644
--- a/test/src/math/smoke/fdim_test.cpp
+++ b/test/src/math/smoke/fdim_test.cpp
@@ -8,26 +8,6 @@
#include "FDimTest.h"
-#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdim.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-using LlvmLibcFDimTest = FDimTestTemplate<double>;
-
-TEST_F(LlvmLibcFDimTest, NaNArg_fdim) { test_na_n_arg(&LIBC_NAMESPACE::fdim); }
-
-TEST_F(LlvmLibcFDimTest, InfArg_fdim) { test_inf_arg(&LIBC_NAMESPACE::fdim); }
-
-TEST_F(LlvmLibcFDimTest, NegInfArg_fdim) {
- test_neg_inf_arg(&LIBC_NAMESPACE::fdim);
-}
-
-TEST_F(LlvmLibcFDimTest, BothZero_fdim) {
- test_both_zero(&LIBC_NAMESPACE::fdim);
-}
-
-TEST_F(LlvmLibcFDimTest, InDoubleRange_fdim) {
- test_in_range(&LIBC_NAMESPACE::fdim);
-}
+LIST_FDIM_TESTS(double, LIBC_NAMESPACE::fdim);
diff --git a/test/src/math/smoke/fdimf128_test.cpp b/test/src/math/smoke/fdimf128_test.cpp
new file mode 100644
index 000000000000..8e65c2b4a1ec
--- /dev/null
+++ b/test/src/math/smoke/fdimf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fdimf128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fdimf128.h"
+
+LIST_FDIM_TESTS(float128, LIBC_NAMESPACE::fdimf128);
diff --git a/test/src/math/smoke/fdimf_test.cpp b/test/src/math/smoke/fdimf_test.cpp
index 27511baf25b6..9c27c1d2fc20 100644
--- a/test/src/math/smoke/fdimf_test.cpp
+++ b/test/src/math/smoke/fdimf_test.cpp
@@ -8,28 +8,6 @@
#include "FDimTest.h"
-#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdimf.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-using LlvmLibcFDimTest = FDimTestTemplate<float>;
-
-TEST_F(LlvmLibcFDimTest, NaNArg_fdimf) {
- test_na_n_arg(&LIBC_NAMESPACE::fdimf);
-}
-
-TEST_F(LlvmLibcFDimTest, InfArg_fdimf) { test_inf_arg(&LIBC_NAMESPACE::fdimf); }
-
-TEST_F(LlvmLibcFDimTest, NegInfArg_fdimf) {
- test_neg_inf_arg(&LIBC_NAMESPACE::fdimf);
-}
-
-TEST_F(LlvmLibcFDimTest, BothZero_fdimf) {
- test_both_zero(&LIBC_NAMESPACE::fdimf);
-}
-
-TEST_F(LlvmLibcFDimTest, InFloatRange_fdimf) {
- test_in_range(&LIBC_NAMESPACE::fdimf);
-}
+LIST_FDIM_TESTS(float, LIBC_NAMESPACE::fdimf);
diff --git a/test/src/math/smoke/fdiml_test.cpp b/test/src/math/smoke/fdiml_test.cpp
index 45aedb0a1cde..ed448a612ec7 100644
--- a/test/src/math/smoke/fdiml_test.cpp
+++ b/test/src/math/smoke/fdiml_test.cpp
@@ -8,28 +8,6 @@
#include "FDimTest.h"
-#include "src/__support/FPUtil/FPBits.h"
#include "src/math/fdiml.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-using LlvmLibcFDimTest = FDimTestTemplate<long double>;
-
-TEST_F(LlvmLibcFDimTest, NaNArg_fdiml) {
- test_na_n_arg(&LIBC_NAMESPACE::fdiml);
-}
-
-TEST_F(LlvmLibcFDimTest, InfArg_fdiml) { test_inf_arg(&LIBC_NAMESPACE::fdiml); }
-
-TEST_F(LlvmLibcFDimTest, NegInfArg_fdiml) {
- test_neg_inf_arg(&LIBC_NAMESPACE::fdiml);
-}
-
-TEST_F(LlvmLibcFDimTest, BothZero_fdiml) {
- test_both_zero(&LIBC_NAMESPACE::fdiml);
-}
-
-TEST_F(LlvmLibcFDimTest, InLongDoubleRange_fdiml) {
- test_in_range(&LIBC_NAMESPACE::fdiml);
-}
+LIST_FDIM_TESTS(long double, LIBC_NAMESPACE::fdiml);
diff --git a/test/src/math/smoke/floorf128_test.cpp b/test/src/math/smoke/floorf128_test.cpp
new file mode 100644
index 000000000000..1858a4aad0ad
--- /dev/null
+++ b/test/src/math/smoke/floorf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for floorf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/floorf128.h"
+
+LIST_FLOOR_TESTS(float128, LIBC_NAMESPACE::floorf128)
diff --git a/test/src/math/smoke/fmaximum_mag_num_test.cpp b/test/src/math/smoke/fmaximum_mag_num_test.cpp
new file mode 100644
index 000000000000..16ec1b0ea343
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_mag_num_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_mag_num-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_mag_num.h"
+
+LIST_FMAXIMUM_MAG_NUM_TESTS(double, LIBC_NAMESPACE::fmaximum_mag_num)
diff --git a/test/src/math/smoke/fmaximum_mag_numf128_test.cpp b/test/src/math/smoke/fmaximum_mag_numf128_test.cpp
new file mode 100644
index 000000000000..17f2a24f7fd0
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_mag_numf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_mag_numf128---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_mag_numf128.h"
+
+LIST_FMAXIMUM_MAG_NUM_TESTS(float128, LIBC_NAMESPACE::fmaximum_mag_numf128)
diff --git a/test/src/math/smoke/fmaximum_mag_numf_test.cpp b/test/src/math/smoke/fmaximum_mag_numf_test.cpp
new file mode 100644
index 000000000000..a8a46f96970e
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_mag_numf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_mag_numf------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_mag_numf.h"
+
+LIST_FMAXIMUM_MAG_NUM_TESTS(float, LIBC_NAMESPACE::fmaximum_mag_numf)
diff --git a/test/src/math/smoke/fmaximum_mag_numl_test.cpp b/test/src/math/smoke/fmaximum_mag_numl_test.cpp
new file mode 100644
index 000000000000..c03fa20bd367
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_mag_numl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_mag_numl------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_mag_numl.h"
+
+LIST_FMAXIMUM_MAG_NUM_TESTS(long double, LIBC_NAMESPACE::fmaximum_mag_numl)
diff --git a/test/src/math/smoke/fmaximum_mag_test.cpp b/test/src/math/smoke/fmaximum_mag_test.cpp
new file mode 100644
index 000000000000..e70602f044ec
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_mag_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_mag-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_mag.h"
+
+LIST_FMAXIMUM_MAG_TESTS(double, LIBC_NAMESPACE::fmaximum_mag)
diff --git a/test/src/math/smoke/fmaximum_magf128_test.cpp b/test/src/math/smoke/fmaximum_magf128_test.cpp
new file mode 100644
index 000000000000..d7ae8ec8d7a0
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_magf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_magf128-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_magf128.h"
+
+LIST_FMAXIMUM_MAG_TESTS(float128, LIBC_NAMESPACE::fmaximum_magf128)
diff --git a/test/src/math/smoke/fmaximum_magf_test.cpp b/test/src/math/smoke/fmaximum_magf_test.cpp
new file mode 100644
index 000000000000..efca320b2b37
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_magf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_magf----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_magf.h"
+
+LIST_FMAXIMUM_MAG_TESTS(float, LIBC_NAMESPACE::fmaximum_magf)
diff --git a/test/src/math/smoke/fmaximum_magl_test.cpp b/test/src/math/smoke/fmaximum_magl_test.cpp
new file mode 100644
index 000000000000..16b420b8714b
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_magl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_magl----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_magl.h"
+
+LIST_FMAXIMUM_MAG_TESTS(long double, LIBC_NAMESPACE::fmaximum_magl)
diff --git a/test/src/math/smoke/fmaximum_num_test.cpp b/test/src/math/smoke/fmaximum_num_test.cpp
new file mode 100644
index 000000000000..cb9afdf78b83
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_num_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_num-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_num.h"
+
+LIST_FMAXIMUM_NUM_TESTS(double, LIBC_NAMESPACE::fmaximum_num)
diff --git a/test/src/math/smoke/fmaximum_numf128_test.cpp b/test/src/math/smoke/fmaximum_numf128_test.cpp
new file mode 100644
index 000000000000..6855ea3b39a9
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_numf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_numf128-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_numf128.h"
+
+LIST_FMAXIMUM_NUM_TESTS(float128, LIBC_NAMESPACE::fmaximum_numf128)
diff --git a/test/src/math/smoke/fmaximum_numf_test.cpp b/test/src/math/smoke/fmaximum_numf_test.cpp
new file mode 100644
index 000000000000..053d18803e07
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_numf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_numf----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_numf.h"
+
+LIST_FMAXIMUM_NUM_TESTS(float, LIBC_NAMESPACE::fmaximum_numf)
diff --git a/test/src/math/smoke/fmaximum_numl_test.cpp b/test/src/math/smoke/fmaximum_numl_test.cpp
new file mode 100644
index 000000000000..bf9612c4111d
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_numl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum_numl----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum_numl.h"
+
+LIST_FMAXIMUM_NUM_TESTS(long double, LIBC_NAMESPACE::fmaximum_numl)
diff --git a/test/src/math/smoke/fmaximum_test.cpp b/test/src/math/smoke/fmaximum_test.cpp
new file mode 100644
index 000000000000..990e0177d868
--- /dev/null
+++ b/test/src/math/smoke/fmaximum_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximum---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximum.h"
+
+LIST_FMAXIMUM_TESTS(double, LIBC_NAMESPACE::fmaximum)
diff --git a/test/src/math/smoke/fmaximumf128_test.cpp b/test/src/math/smoke/fmaximumf128_test.cpp
new file mode 100644
index 000000000000..7e0b97bcdd4d
--- /dev/null
+++ b/test/src/math/smoke/fmaximumf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximumf128-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximumf128.h"
+
+LIST_FMAXIMUM_TESTS(float128, LIBC_NAMESPACE::fmaximumf128)
diff --git a/test/src/math/smoke/fmaximumf_test.cpp b/test/src/math/smoke/fmaximumf_test.cpp
new file mode 100644
index 000000000000..a92bbd1446e7
--- /dev/null
+++ b/test/src/math/smoke/fmaximumf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximumf--------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximumf.h"
+
+LIST_FMAXIMUM_TESTS(float, LIBC_NAMESPACE::fmaximumf)
diff --git a/test/src/math/smoke/fmaximuml_test.cpp b/test/src/math/smoke/fmaximuml_test.cpp
new file mode 100644
index 000000000000..080847b9f4de
--- /dev/null
+++ b/test/src/math/smoke/fmaximuml_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmaximuml--------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmaximuml.h"
+
+LIST_FMAXIMUM_TESTS(long double, LIBC_NAMESPACE::fmaximuml)
diff --git a/test/src/math/smoke/fminimum_mag_num_test.cpp b/test/src/math/smoke/fminimum_mag_num_test.cpp
new file mode 100644
index 000000000000..471f2ceb3c2c
--- /dev/null
+++ b/test/src/math/smoke/fminimum_mag_num_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_mag_num-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_mag_num.h"
+
+LIST_FMINIMUM_MAG_NUM_TESTS(double, LIBC_NAMESPACE::fminimum_mag_num)
diff --git a/test/src/math/smoke/fminimum_mag_numf128_test.cpp b/test/src/math/smoke/fminimum_mag_numf128_test.cpp
new file mode 100644
index 000000000000..f1db025f4895
--- /dev/null
+++ b/test/src/math/smoke/fminimum_mag_numf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_mag_numf128---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_mag_numf128.h"
+
+LIST_FMINIMUM_MAG_NUM_TESTS(float128, LIBC_NAMESPACE::fminimum_mag_numf128)
diff --git a/test/src/math/smoke/fminimum_mag_numf_test.cpp b/test/src/math/smoke/fminimum_mag_numf_test.cpp
new file mode 100644
index 000000000000..773ba806b99e
--- /dev/null
+++ b/test/src/math/smoke/fminimum_mag_numf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_mag_numf------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_mag_numf.h"
+
+LIST_FMINIMUM_MAG_NUM_TESTS(float, LIBC_NAMESPACE::fminimum_mag_numf)
diff --git a/test/src/math/smoke/fminimum_mag_numl_test.cpp b/test/src/math/smoke/fminimum_mag_numl_test.cpp
new file mode 100644
index 000000000000..b4152779db73
--- /dev/null
+++ b/test/src/math/smoke/fminimum_mag_numl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_mag_numl------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_mag_numl.h"
+
+LIST_FMINIMUM_MAG_NUM_TESTS(long double, LIBC_NAMESPACE::fminimum_mag_numl)
diff --git a/test/src/math/smoke/fminimum_mag_test.cpp b/test/src/math/smoke/fminimum_mag_test.cpp
new file mode 100644
index 000000000000..f4138f3353d1
--- /dev/null
+++ b/test/src/math/smoke/fminimum_mag_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_mag-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_mag.h"
+
+LIST_FMINIMUM_MAG_TESTS(double, LIBC_NAMESPACE::fminimum_mag)
diff --git a/test/src/math/smoke/fminimum_magf128_test.cpp b/test/src/math/smoke/fminimum_magf128_test.cpp
new file mode 100644
index 000000000000..010ee6e73bee
--- /dev/null
+++ b/test/src/math/smoke/fminimum_magf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_magf128-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_magf128.h"
+
+LIST_FMINIMUM_MAG_TESTS(float128, LIBC_NAMESPACE::fminimum_magf128)
diff --git a/test/src/math/smoke/fminimum_magf_test.cpp b/test/src/math/smoke/fminimum_magf_test.cpp
new file mode 100644
index 000000000000..aa2743148930
--- /dev/null
+++ b/test/src/math/smoke/fminimum_magf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_magf----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_magf.h"
+
+LIST_FMINIMUM_MAG_TESTS(float, LIBC_NAMESPACE::fminimum_magf)
diff --git a/test/src/math/smoke/fminimum_magl_test.cpp b/test/src/math/smoke/fminimum_magl_test.cpp
new file mode 100644
index 000000000000..c6fbf7df0e70
--- /dev/null
+++ b/test/src/math/smoke/fminimum_magl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_magl----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_magl.h"
+
+LIST_FMINIMUM_MAG_TESTS(long double, LIBC_NAMESPACE::fminimum_magl)
diff --git a/test/src/math/smoke/fminimum_num_test.cpp b/test/src/math/smoke/fminimum_num_test.cpp
new file mode 100644
index 000000000000..1be7ebb5fe8e
--- /dev/null
+++ b/test/src/math/smoke/fminimum_num_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_num-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_num.h"
+
+LIST_FMINIMUM_NUM_TESTS(double, LIBC_NAMESPACE::fminimum_num)
diff --git a/test/src/math/smoke/fminimum_numf128_test.cpp b/test/src/math/smoke/fminimum_numf128_test.cpp
new file mode 100644
index 000000000000..d773d8973286
--- /dev/null
+++ b/test/src/math/smoke/fminimum_numf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_numf128-------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_numf128.h"
+
+LIST_FMINIMUM_NUM_TESTS(float128, LIBC_NAMESPACE::fminimum_numf128)
diff --git a/test/src/math/smoke/fminimum_numf_test.cpp b/test/src/math/smoke/fminimum_numf_test.cpp
new file mode 100644
index 000000000000..9b60f39d55a8
--- /dev/null
+++ b/test/src/math/smoke/fminimum_numf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_numf----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_numf.h"
+
+LIST_FMINIMUM_NUM_TESTS(float, LIBC_NAMESPACE::fminimum_numf)
diff --git a/test/src/math/smoke/fminimum_numl_test.cpp b/test/src/math/smoke/fminimum_numl_test.cpp
new file mode 100644
index 000000000000..8a72cd8adc5b
--- /dev/null
+++ b/test/src/math/smoke/fminimum_numl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum_numl----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum_numl.h"
+
+LIST_FMINIMUM_NUM_TESTS(long double, LIBC_NAMESPACE::fminimum_numl)
diff --git a/test/src/math/smoke/fminimum_test.cpp b/test/src/math/smoke/fminimum_test.cpp
new file mode 100644
index 000000000000..7778f1c2311c
--- /dev/null
+++ b/test/src/math/smoke/fminimum_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimum---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimum.h"
+
+LIST_FMINIMUM_TESTS(double, LIBC_NAMESPACE::fminimum)
diff --git a/test/src/math/smoke/fminimumf128_test.cpp b/test/src/math/smoke/fminimumf128_test.cpp
new file mode 100644
index 000000000000..163090b8a9ec
--- /dev/null
+++ b/test/src/math/smoke/fminimumf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimumf128-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimumf128.h"
+
+LIST_FMINIMUM_TESTS(float128, LIBC_NAMESPACE::fminimumf128)
diff --git a/test/src/math/smoke/fminimumf_test.cpp b/test/src/math/smoke/fminimumf_test.cpp
new file mode 100644
index 000000000000..2ca0f2f35a7f
--- /dev/null
+++ b/test/src/math/smoke/fminimumf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimumf--------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimumf.h"
+
+LIST_FMINIMUM_TESTS(float, LIBC_NAMESPACE::fminimumf)
diff --git a/test/src/math/smoke/fminimuml_test.cpp b/test/src/math/smoke/fminimuml_test.cpp
new file mode 100644
index 000000000000..3c067ae23f45
--- /dev/null
+++ b/test/src/math/smoke/fminimuml_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fminimuml--------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fminimuml.h"
+
+LIST_FMINIMUM_TESTS(long double, LIBC_NAMESPACE::fminimuml)
diff --git a/test/src/math/smoke/fmodf128_test.cpp b/test/src/math/smoke/fmodf128_test.cpp
new file mode 100644
index 000000000000..f75aadac8438
--- /dev/null
+++ b/test/src/math/smoke/fmodf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmodf128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmodf128.h"
+
+LIST_FMOD_TESTS(float128, LIBC_NAMESPACE::fmodf128)
diff --git a/test/src/math/smoke/fmodl_test.cpp b/test/src/math/smoke/fmodl_test.cpp
new file mode 100644
index 000000000000..b69ed8ec85c8
--- /dev/null
+++ b/test/src/math/smoke/fmodl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmodl -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fmodl.h"
+
+LIST_FMOD_TESTS(long double, LIBC_NAMESPACE::fmodl)
diff --git a/test/src/math/smoke/frexp_test.cpp b/test/src/math/smoke/frexp_test.cpp
index 4d078baffcb3..79aa9723d314 100644
--- a/test/src/math/smoke/frexp_test.cpp
+++ b/test/src/math/smoke/frexp_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexp.h"
-LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp)
+LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp);
diff --git a/test/src/math/smoke/frexpf128_test.cpp b/test/src/math/smoke/frexpf128_test.cpp
new file mode 100644
index 000000000000..a0df32f5fbdd
--- /dev/null
+++ b/test/src/math/smoke/frexpf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for frexpf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/frexpf128.h"
+
+LIST_FREXP_TESTS(float128, LIBC_NAMESPACE::frexpf128);
diff --git a/test/src/math/smoke/frexpf_test.cpp b/test/src/math/smoke/frexpf_test.cpp
index 577eb9609cfc..f2ae637e9a6c 100644
--- a/test/src/math/smoke/frexpf_test.cpp
+++ b/test/src/math/smoke/frexpf_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexpf.h"
-LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf)
+LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf);
diff --git a/test/src/math/smoke/frexpl_test.cpp b/test/src/math/smoke/frexpl_test.cpp
index e5184cd225bc..3e1f8b4204e6 100644
--- a/test/src/math/smoke/frexpl_test.cpp
+++ b/test/src/math/smoke/frexpl_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexpl.h"
-LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl)
+LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl);
diff --git a/test/src/math/smoke/fromfp_test.cpp b/test/src/math/smoke/fromfp_test.cpp
new file mode 100644
index 000000000000..147a9df9afcf
--- /dev/null
+++ b/test/src/math/smoke/fromfp_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfp.h"
+
+LIST_FROMFP_TESTS(double, LIBC_NAMESPACE::fromfp)
diff --git a/test/src/math/smoke/fromfpf128_test.cpp b/test/src/math/smoke/fromfpf128_test.cpp
new file mode 100644
index 000000000000..288aadb359bf
--- /dev/null
+++ b/test/src/math/smoke/fromfpf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpf128 ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpf128.h"
+
+LIST_FROMFP_TESTS(float128, LIBC_NAMESPACE::fromfpf128)
diff --git a/test/src/math/smoke/fromfpf_test.cpp b/test/src/math/smoke/fromfpf_test.cpp
new file mode 100644
index 000000000000..63f3f624716e
--- /dev/null
+++ b/test/src/math/smoke/fromfpf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpf ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpf.h"
+
+LIST_FROMFP_TESTS(float, LIBC_NAMESPACE::fromfpf)
diff --git a/test/src/math/smoke/fromfpl_test.cpp b/test/src/math/smoke/fromfpl_test.cpp
new file mode 100644
index 000000000000..c0072768870b
--- /dev/null
+++ b/test/src/math/smoke/fromfpl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpl ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpl.h"
+
+LIST_FROMFP_TESTS(long double, LIBC_NAMESPACE::fromfpl)
diff --git a/test/src/math/smoke/fromfpx_test.cpp b/test/src/math/smoke/fromfpx_test.cpp
new file mode 100644
index 000000000000..10b1eee726e1
--- /dev/null
+++ b/test/src/math/smoke/fromfpx_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpx ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpx.h"
+
+LIST_FROMFPX_TESTS(double, LIBC_NAMESPACE::fromfpx)
diff --git a/test/src/math/smoke/fromfpxf128_test.cpp b/test/src/math/smoke/fromfpxf128_test.cpp
new file mode 100644
index 000000000000..2839bed30cb7
--- /dev/null
+++ b/test/src/math/smoke/fromfpxf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpxf128 -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpxf128.h"
+
+LIST_FROMFPX_TESTS(float128, LIBC_NAMESPACE::fromfpxf128)
diff --git a/test/src/math/smoke/fromfpxf_test.cpp b/test/src/math/smoke/fromfpxf_test.cpp
new file mode 100644
index 000000000000..42e47aba40ae
--- /dev/null
+++ b/test/src/math/smoke/fromfpxf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpxf --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpxf.h"
+
+LIST_FROMFPX_TESTS(float, LIBC_NAMESPACE::fromfpxf)
diff --git a/test/src/math/smoke/fromfpxl_test.cpp b/test/src/math/smoke/fromfpxl_test.cpp
new file mode 100644
index 000000000000..cbe8d750ff2a
--- /dev/null
+++ b/test/src/math/smoke/fromfpxl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpxl --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/fromfpxl.h"
+
+LIST_FROMFPX_TESTS(long double, LIBC_NAMESPACE::fromfpxl)
diff --git a/test/src/math/smoke/ilogb_test.cpp b/test/src/math/smoke/ilogb_test.cpp
index 7011c43386e6..67c7939608e8 100644
--- a/test/src/math/smoke/ilogb_test.cpp
+++ b/test/src/math/smoke/ilogb_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogb.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogb) {
- test_special_numbers<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogb) {
- test_powers_of_two<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogb) {
- test_some_integers<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogb) {
- test_subnormal_range<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogb) {
- test_normal_range<double>(&LIBC_NAMESPACE::ilogb);
-}
+LIST_INTLOGB_TESTS(int, double, LIBC_NAMESPACE::ilogb);
diff --git a/test/src/math/smoke/ilogbf128_test.cpp b/test/src/math/smoke/ilogbf128_test.cpp
new file mode 100644
index 000000000000..21ed0dd112b9
--- /dev/null
+++ b/test/src/math/smoke/ilogbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ilogbf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ilogbf128.h"
+
+LIST_INTLOGB_TESTS(int, float128, LIBC_NAMESPACE::ilogbf128);
diff --git a/test/src/math/smoke/ilogbf_test.cpp b/test/src/math/smoke/ilogbf_test.cpp
index dcff8eeb1518..68e6950cdf72 100644
--- a/test/src/math/smoke/ilogbf_test.cpp
+++ b/test/src/math/smoke/ilogbf_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbf.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbf) {
- test_special_numbers<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogbf) {
- test_powers_of_two<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogbf) {
- test_some_integers<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogbf) {
- test_subnormal_range<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogbf) {
- test_normal_range<float>(&LIBC_NAMESPACE::ilogbf);
-}
+LIST_INTLOGB_TESTS(int, float, LIBC_NAMESPACE::ilogbf);
diff --git a/test/src/math/smoke/ilogbl_test.cpp b/test/src/math/smoke/ilogbl_test.cpp
index 29a221ad7f08..afc961f16863 100644
--- a/test/src/math/smoke/ilogbl_test.cpp
+++ b/test/src/math/smoke/ilogbl_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbl.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbl) {
- test_special_numbers<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogbl) {
- test_powers_of_two<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogbl) {
- test_some_integers<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogbl) {
- test_subnormal_range<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogbl) {
- test_normal_range<long double>(&LIBC_NAMESPACE::ilogbl);
-}
+LIST_INTLOGB_TESTS(int, long double, LIBC_NAMESPACE::ilogbl);
diff --git a/test/src/math/smoke/ldexp_test.cpp b/test/src/math/smoke/ldexp_test.cpp
index aad580f95fb9..adbf603b1e96 100644
--- a/test/src/math/smoke/ldexp_test.cpp
+++ b/test/src/math/smoke/ldexp_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/ldexp.h"
-LIST_LDEXP_TESTS(double, LIBC_NAMESPACE::ldexp)
+LIST_LDEXP_TESTS(double, LIBC_NAMESPACE::ldexp);
diff --git a/test/src/math/smoke/ldexpf128_test.cpp b/test/src/math/smoke/ldexpf128_test.cpp
new file mode 100644
index 000000000000..7ab34a4ce15d
--- /dev/null
+++ b/test/src/math/smoke/ldexpf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ldexpf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ldexpf128.h"
+
+LIST_LDEXP_TESTS(float128, LIBC_NAMESPACE::ldexpf128);
diff --git a/test/src/math/smoke/ldexpf_test.cpp b/test/src/math/smoke/ldexpf_test.cpp
index f4cce37b9277..02fd8c56effc 100644
--- a/test/src/math/smoke/ldexpf_test.cpp
+++ b/test/src/math/smoke/ldexpf_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/ldexpf.h"
-LIST_LDEXP_TESTS(float, LIBC_NAMESPACE::ldexpf)
+LIST_LDEXP_TESTS(float, LIBC_NAMESPACE::ldexpf);
diff --git a/test/src/math/smoke/ldexpl_test.cpp b/test/src/math/smoke/ldexpl_test.cpp
index 405e53390e8c..9bc17c5c7df7 100644
--- a/test/src/math/smoke/ldexpl_test.cpp
+++ b/test/src/math/smoke/ldexpl_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/ldexpl.h"
-LIST_LDEXP_TESTS(long double, LIBC_NAMESPACE::ldexpl)
+LIST_LDEXP_TESTS(long double, LIBC_NAMESPACE::ldexpl);
diff --git a/test/src/math/smoke/llogb_test.cpp b/test/src/math/smoke/llogb_test.cpp
new file mode 100644
index 000000000000..3bccded6c3e3
--- /dev/null
+++ b/test/src/math/smoke/llogb_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogb -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llogb.h"
+
+LIST_INTLOGB_TESTS(long, double, LIBC_NAMESPACE::llogb);
diff --git a/test/src/math/smoke/llogbf128_test.cpp b/test/src/math/smoke/llogbf128_test.cpp
new file mode 100644
index 000000000000..a1d2021d2a37
--- /dev/null
+++ b/test/src/math/smoke/llogbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llogbf128.h"
+
+LIST_INTLOGB_TESTS(long, float128, LIBC_NAMESPACE::llogbf128);
diff --git a/test/src/math/smoke/llogbf_test.cpp b/test/src/math/smoke/llogbf_test.cpp
new file mode 100644
index 000000000000..60c92fbc2c46
--- /dev/null
+++ b/test/src/math/smoke/llogbf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbf ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llogbf.h"
+
+LIST_INTLOGB_TESTS(long, float, LIBC_NAMESPACE::llogbf);
diff --git a/test/src/math/smoke/llogbl_test.cpp b/test/src/math/smoke/llogbl_test.cpp
new file mode 100644
index 000000000000..c698210fc3de
--- /dev/null
+++ b/test/src/math/smoke/llogbl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbl ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llogbl.h"
+
+LIST_INTLOGB_TESTS(long, long double, LIBC_NAMESPACE::llogbl);
diff --git a/test/src/math/smoke/llrintf128_test.cpp b/test/src/math/smoke/llrintf128_test.cpp
new file mode 100644
index 000000000000..8847b2918e63
--- /dev/null
+++ b/test/src/math/smoke/llrintf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for llrintf128 ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llrintf128.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(float128, long long,
+ LIBC_NAMESPACE::llrintf128)
diff --git a/test/src/math/smoke/llroundf128_test.cpp b/test/src/math/smoke/llroundf128_test.cpp
new file mode 100644
index 000000000000..b00055e759f8
--- /dev/null
+++ b/test/src/math/smoke/llroundf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llroundf128 -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/llroundf128.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(float128, long long, LIBC_NAMESPACE::llroundf128)
diff --git a/test/src/math/smoke/log10_test.cpp b/test/src/math/smoke/log10_test.cpp
index c1658a3d5c96..36d753419764 100644
--- a/test/src/math/smoke/log10_test.cpp
+++ b/test/src/math/smoke/log10_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log10f_test.cpp b/test/src/math/smoke/log10f_test.cpp
index 53950233cabf..53e699417fb7 100644
--- a/test/src/math/smoke/log10f_test.cpp
+++ b/test/src/math/smoke/log10f_test.cpp
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log1p_test.cpp b/test/src/math/smoke/log1p_test.cpp
index e1966c28397c..5fe9c60f90ab 100644
--- a/test/src/math/smoke/log1p_test.cpp
+++ b/test/src/math/smoke/log1p_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log1p.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log1pf_test.cpp b/test/src/math/smoke/log1pf_test.cpp
index 377a46adef9c..e2fb2f057d2e 100644
--- a/test/src/math/smoke/log1pf_test.cpp
+++ b/test/src/math/smoke/log1pf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log1pf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log2_test.cpp b/test/src/math/smoke/log2_test.cpp
index 826c51eb8c1b..fbeba9527bcb 100644
--- a/test/src/math/smoke/log2_test.cpp
+++ b/test/src/math/smoke/log2_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log2f_test.cpp b/test/src/math/smoke/log2f_test.cpp
index 2387ff59d70d..46906e78dcaf 100644
--- a/test/src/math/smoke/log2f_test.cpp
+++ b/test/src/math/smoke/log2f_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/log_test.cpp b/test/src/math/smoke/log_test.cpp
index 423b9d8bb818..b1e390599480 100644
--- a/test/src/math/smoke/log_test.cpp
+++ b/test/src/math/smoke/log_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/log.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/logbf128_test.cpp b/test/src/math/smoke/logbf128_test.cpp
new file mode 100644
index 000000000000..49485f8ee714
--- /dev/null
+++ b/test/src/math/smoke/logbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for logbf128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/logbf128.h"
+
+LIST_LOGB_TESTS(float128, LIBC_NAMESPACE::logbf128)
diff --git a/test/src/math/smoke/logf_test.cpp b/test/src/math/smoke/logf_test.cpp
index 21b39ee6896d..97b6bdde307b 100644
--- a/test/src/math/smoke/logf_test.cpp
+++ b/test/src/math/smoke/logf_test.cpp
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/logf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/lrintf128_test.cpp b/test/src/math/smoke/lrintf128_test.cpp
new file mode 100644
index 000000000000..a559ccf0eda7
--- /dev/null
+++ b/test/src/math/smoke/lrintf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for lrintf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/lrintf128.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(float128, long,
+ LIBC_NAMESPACE::lrintf128)
diff --git a/test/src/math/smoke/lroundf128_test.cpp b/test/src/math/smoke/lroundf128_test.cpp
new file mode 100644
index 000000000000..ed87c9af0489
--- /dev/null
+++ b/test/src/math/smoke/lroundf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for lroundf128 ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/lroundf128.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(float128, long, LIBC_NAMESPACE::lroundf128)
diff --git a/test/src/math/smoke/modff128_test.cpp b/test/src/math/smoke/modff128_test.cpp
new file mode 100644
index 000000000000..062d40138e72
--- /dev/null
+++ b/test/src/math/smoke/modff128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for modff128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/modff128.h"
+
+LIST_MODF_TESTS(float128, LIBC_NAMESPACE::modff128)
diff --git a/test/src/math/smoke/nanf128_test.cpp b/test/src/math/smoke/nanf128_test.cpp
new file mode 100644
index 000000000000..2a9f57de5b43
--- /dev/null
+++ b/test/src/math/smoke/nanf128_test.cpp
@@ -0,0 +1,60 @@
+//===-- Unittests for nanf128 ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/UInt128.h"
+#include "src/math/nanf128.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::Test {
+public:
+ using FPBits128 = LIBC_NAMESPACE::fputil::FPBits<float128>;
+ using StorageType = FPBits128::StorageType;
+
+ const UInt128 QUIET_NAN = FPBits128::quiet_nan().uintval();
+ const UInt128 ONE = UInt128(1);
+
+ void run_test(const char *input_str, StorageType bits) {
+ float128 result = LIBC_NAMESPACE::nanf128(input_str);
+ auto actual_fp = FPBits128(result);
+ auto expected_fp = FPBits128(bits);
+ EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval());
+ };
+};
+
+TEST_F(LlvmLibcNanf128Test, NCharSeq) {
+ run_test("", QUIET_NAN);
+ run_test("1234", QUIET_NAN | 1234);
+ run_test("0x1234", QUIET_NAN | 0x1234);
+ run_test("2417851639229258349412352", QUIET_NAN | (ONE << 81));
+ run_test("0x200000000000000000000", QUIET_NAN | (ONE << 81));
+ run_test("10384593717069655257060992658440191",
+ QUIET_NAN | FPBits128::SIG_MASK);
+ run_test("0x1ffffffffffffffffffffffffffff", QUIET_NAN | FPBits128::SIG_MASK);
+ run_test("10384593717069655257060992658440192", QUIET_NAN);
+ run_test("0x20000000000000000000000000000", QUIET_NAN);
+ run_test("1a", QUIET_NAN);
+ run_test("10000000000000000000000000000000000000000000000000", QUIET_NAN);
+}
+
+TEST_F(LlvmLibcNanf128Test, RandomString) {
+ run_test(" 1234", QUIET_NAN);
+ run_test("-1234", QUIET_NAN);
+ run_test("asd&f", QUIET_NAN);
+ run_test("123 ", QUIET_NAN);
+ run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+ QUIET_NAN);
+}
+
+#ifndef LIBC_HAVE_ADDRESS_SANITIZER
+#include <signal.h>
+TEST_F(LlvmLibcNanf128Test, InvalidInput) {
+ EXPECT_DEATH([] { LIBC_NAMESPACE::nanf128(nullptr); }, WITH_SIGNAL(SIGSEGV));
+}
+#endif // LIBC_HAVE_ADDRESS_SANITIZER
diff --git a/test/src/math/smoke/nanl_test.cpp b/test/src/math/smoke/nanl_test.cpp
index 009710b49c83..5ff70a94b54d 100644
--- a/test/src/math/smoke/nanl_test.cpp
+++ b/test/src/math/smoke/nanl_test.cpp
@@ -12,12 +12,14 @@
#include "test/UnitTest/Test.h"
#include <signal.h>
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
#define SELECT_LONG_DOUBLE(val, _, __) val
-#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#define SELECT_LONG_DOUBLE(_, val, __) val
-#else
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
#define SELECT_LONG_DOUBLE(_, __, val) val
+#else
+#error "Unknown long double type"
#endif
class LlvmLibcNanlTest : public LIBC_NAMESPACE::testing::Test {
diff --git a/test/src/math/smoke/nextafterf128_test.cpp b/test/src/math/smoke/nextafterf128_test.cpp
new file mode 100644
index 000000000000..a8d000ff4de3
--- /dev/null
+++ b/test/src/math/smoke/nextafterf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextafterf128 ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextafterf128.h"
+
+LIST_NEXTAFTER_TESTS(float128, LIBC_NAMESPACE::nextafterf128)
diff --git a/test/src/math/smoke/nextdown_test.cpp b/test/src/math/smoke/nextdown_test.cpp
new file mode 100644
index 000000000000..6b0f5c6c5a6a
--- /dev/null
+++ b/test/src/math/smoke/nextdown_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdown --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextdown.h"
+
+LIST_NEXTDOWN_TESTS(double, LIBC_NAMESPACE::nextdown)
diff --git a/test/src/math/smoke/nextdownf128_test.cpp b/test/src/math/smoke/nextdownf128_test.cpp
new file mode 100644
index 000000000000..932a8b36a59e
--- /dev/null
+++ b/test/src/math/smoke/nextdownf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownf128 ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextdownf128.h"
+
+LIST_NEXTDOWN_TESTS(float128, LIBC_NAMESPACE::nextdownf128)
diff --git a/test/src/math/smoke/nextdownf_test.cpp b/test/src/math/smoke/nextdownf_test.cpp
new file mode 100644
index 000000000000..3c05c22d8204
--- /dev/null
+++ b/test/src/math/smoke/nextdownf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownf -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextdownf.h"
+
+LIST_NEXTDOWN_TESTS(float, LIBC_NAMESPACE::nextdownf)
diff --git a/test/src/math/smoke/nextdownl_test.cpp b/test/src/math/smoke/nextdownl_test.cpp
new file mode 100644
index 000000000000..f1785eb58ce5
--- /dev/null
+++ b/test/src/math/smoke/nextdownl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownl -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextdownl.h"
+
+LIST_NEXTDOWN_TESTS(long double, LIBC_NAMESPACE::nextdownl)
diff --git a/test/src/math/smoke/nextup_test.cpp b/test/src/math/smoke/nextup_test.cpp
new file mode 100644
index 000000000000..04c73ac9492f
--- /dev/null
+++ b/test/src/math/smoke/nextup_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextup ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextup.h"
+
+LIST_NEXTUP_TESTS(double, LIBC_NAMESPACE::nextup)
diff --git a/test/src/math/smoke/nextupf128_test.cpp b/test/src/math/smoke/nextupf128_test.cpp
new file mode 100644
index 000000000000..ddd385a7b159
--- /dev/null
+++ b/test/src/math/smoke/nextupf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupf128 ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextupf128.h"
+
+LIST_NEXTUP_TESTS(float128, LIBC_NAMESPACE::nextupf128)
diff --git a/test/src/math/smoke/nextupf_test.cpp b/test/src/math/smoke/nextupf_test.cpp
new file mode 100644
index 000000000000..df73bee01171
--- /dev/null
+++ b/test/src/math/smoke/nextupf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupf ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextupf.h"
+
+LIST_NEXTUP_TESTS(float, LIBC_NAMESPACE::nextupf)
diff --git a/test/src/math/smoke/nextupl_test.cpp b/test/src/math/smoke/nextupl_test.cpp
new file mode 100644
index 000000000000..50f765633c2a
--- /dev/null
+++ b/test/src/math/smoke/nextupl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupl ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/nextupl.h"
+
+LIST_NEXTUP_TESTS(long double, LIBC_NAMESPACE::nextupl)
diff --git a/test/src/math/smoke/powf_test.cpp b/test/src/math/smoke/powf_test.cpp
index 1867dde0ac3b..e9de1554ec61 100644
--- a/test/src/math/smoke/powf_test.cpp
+++ b/test/src/math/smoke/powf_test.cpp
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/powf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
diff --git a/test/src/math/smoke/rintf128_test.cpp b/test/src/math/smoke/rintf128_test.cpp
new file mode 100644
index 000000000000..11078d795bac
--- /dev/null
+++ b/test/src/math/smoke/rintf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for rintf128 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/rintf128.h"
+
+LIST_RINT_TESTS(float128, LIBC_NAMESPACE::rintf128)
diff --git a/test/src/math/smoke/roundeven_test.cpp b/test/src/math/smoke/roundeven_test.cpp
new file mode 100644
index 000000000000..e2d625fb0d31
--- /dev/null
+++ b/test/src/math/smoke/roundeven_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for roundeven -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundeven.h"
+
+LIST_ROUNDEVEN_TESTS(double, LIBC_NAMESPACE::roundeven)
diff --git a/test/src/math/smoke/roundevenf128_test.cpp b/test/src/math/smoke/roundevenf128_test.cpp
new file mode 100644
index 000000000000..a1fdc40d577e
--- /dev/null
+++ b/test/src/math/smoke/roundevenf128_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for roundevenf128 ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundevenf128.h"
+
+LIST_ROUNDEVEN_TESTS(float128, LIBC_NAMESPACE::roundevenf128)
diff --git a/test/src/math/smoke/roundevenf_test.cpp b/test/src/math/smoke/roundevenf_test.cpp
new file mode 100644
index 000000000000..f033e26988fa
--- /dev/null
+++ b/test/src/math/smoke/roundevenf_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for roundevenf ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundevenf.h"
+
+LIST_ROUNDEVEN_TESTS(float, LIBC_NAMESPACE::roundevenf)
diff --git a/test/src/math/smoke/roundevenl_test.cpp b/test/src/math/smoke/roundevenl_test.cpp
new file mode 100644
index 000000000000..be09f1283aa7
--- /dev/null
+++ b/test/src/math/smoke/roundevenl_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for roundevenf ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundevenl.h"
+
+LIST_ROUNDEVEN_TESTS(long double, LIBC_NAMESPACE::roundevenl)
diff --git a/test/src/math/smoke/roundf128_test.cpp b/test/src/math/smoke/roundf128_test.cpp
new file mode 100644
index 000000000000..01c70c87667b
--- /dev/null
+++ b/test/src/math/smoke/roundf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/roundf128.h"
+
+LIST_ROUND_TESTS(float128, LIBC_NAMESPACE::roundf128)
diff --git a/test/src/math/smoke/sincosf_test.cpp b/test/src/math/smoke/sincosf_test.cpp
index 0de47f3307fe..5952b20fc5bf 100644
--- a/test/src/math/smoke/sincosf_test.cpp
+++ b/test/src/math/smoke/sincosf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/sincosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcSinCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinCosfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float sin, cos;
LIBC_NAMESPACE::sincosf(aNaN, &sin, &cos);
diff --git a/test/src/math/smoke/sinf_test.cpp b/test/src/math/smoke/sinf_test.cpp
index bbd7634e0028..945089504187 100644
--- a/test/src/math/smoke/sinf_test.cpp
+++ b/test/src/math/smoke/sinf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/sinf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcSinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/sinhf_test.cpp b/test/src/math/smoke/sinhf_test.cpp
index 0563ccbf77aa..0f005f752e69 100644
--- a/test/src/math/smoke/sinhf_test.cpp
+++ b/test/src/math/smoke/sinhf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/sinhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -20,7 +20,7 @@
using LlvmLibcSinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinhf(aNaN));
EXPECT_MATH_ERRNO(0);
@@ -50,7 +50,7 @@ TEST_F(LlvmLibcSinhfTest, SmallValues) {
}
TEST_F(LlvmLibcSinhfTest, Overflow) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ_WITH_EXCEPTION(
inf, LIBC_NAMESPACE::sinhf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
diff --git a/test/src/math/smoke/tanf_test.cpp b/test/src/math/smoke/tanf_test.cpp
index fa93da29829a..68bf493f7e82 100644
--- a/test/src/math/smoke/tanf_test.cpp
+++ b/test/src/math/smoke/tanf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/tanf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcTanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcTanfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/tanhf_test.cpp b/test/src/math/smoke/tanhf_test.cpp
index f32e8cc9591f..f1ce8b40d43a 100644
--- a/test/src/math/smoke/tanhf_test.cpp
+++ b/test/src/math/smoke/tanhf_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/tanhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -19,7 +19,7 @@
using LlvmLibcTanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcTanhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanhf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/smoke/truncf128_test.cpp b/test/src/math/smoke/truncf128_test.cpp
new file mode 100644
index 000000000000..7d6487b7d856
--- /dev/null
+++ b/test/src/math/smoke/truncf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for truncf128 -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/truncf128.h"
+
+LIST_TRUNC_TESTS(float128, LIBC_NAMESPACE::truncf128)
diff --git a/test/src/math/smoke/ufromfp_test.cpp b/test/src/math/smoke/ufromfp_test.cpp
new file mode 100644
index 000000000000..ff4762112400
--- /dev/null
+++ b/test/src/math/smoke/ufromfp_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfp.h"
+
+LIST_UFROMFP_TESTS(double, LIBC_NAMESPACE::ufromfp)
diff --git a/test/src/math/smoke/ufromfpf128_test.cpp b/test/src/math/smoke/ufromfpf128_test.cpp
new file mode 100644
index 000000000000..9ba3034f6e61
--- /dev/null
+++ b/test/src/math/smoke/ufromfpf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpf128 -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpf128.h"
+
+LIST_UFROMFP_TESTS(float128, LIBC_NAMESPACE::ufromfpf128)
diff --git a/test/src/math/smoke/ufromfpf_test.cpp b/test/src/math/smoke/ufromfpf_test.cpp
new file mode 100644
index 000000000000..2913b31e20bd
--- /dev/null
+++ b/test/src/math/smoke/ufromfpf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpf --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpf.h"
+
+LIST_UFROMFP_TESTS(float, LIBC_NAMESPACE::ufromfpf)
diff --git a/test/src/math/smoke/ufromfpl_test.cpp b/test/src/math/smoke/ufromfpl_test.cpp
new file mode 100644
index 000000000000..8976056756e4
--- /dev/null
+++ b/test/src/math/smoke/ufromfpl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpl --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpl.h"
+
+LIST_UFROMFP_TESTS(long double, LIBC_NAMESPACE::ufromfpl)
diff --git a/test/src/math/smoke/ufromfpx_test.cpp b/test/src/math/smoke/ufromfpx_test.cpp
new file mode 100644
index 000000000000..3bb45e428f28
--- /dev/null
+++ b/test/src/math/smoke/ufromfpx_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpx --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpx.h"
+
+LIST_UFROMFPX_TESTS(double, LIBC_NAMESPACE::ufromfpx)
diff --git a/test/src/math/smoke/ufromfpxf128_test.cpp b/test/src/math/smoke/ufromfpxf128_test.cpp
new file mode 100644
index 000000000000..6defaf7fee3d
--- /dev/null
+++ b/test/src/math/smoke/ufromfpxf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpxf128 ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpxf128.h"
+
+LIST_UFROMFPX_TESTS(float128, LIBC_NAMESPACE::ufromfpxf128)
diff --git a/test/src/math/smoke/ufromfpxf_test.cpp b/test/src/math/smoke/ufromfpxf_test.cpp
new file mode 100644
index 000000000000..862fd4c2cdac
--- /dev/null
+++ b/test/src/math/smoke/ufromfpxf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpxf -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpxf.h"
+
+LIST_UFROMFPX_TESTS(float, LIBC_NAMESPACE::ufromfpxf)
diff --git a/test/src/math/smoke/ufromfpxl_test.cpp b/test/src/math/smoke/ufromfpxl_test.cpp
new file mode 100644
index 000000000000..b6b93b38e6be
--- /dev/null
+++ b/test/src/math/smoke/ufromfpxl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpxl -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/math/ufromfpxl.h"
+
+LIST_UFROMFPX_TESTS(long double, LIBC_NAMESPACE::ufromfpxl)
diff --git a/test/src/math/tan_test.cpp b/test/src/math/tan_test.cpp
index 9cdc7c4abd32..85174db9364e 100644
--- a/test/src/math/tan_test.cpp
+++ b/test/src/math/tan_test.cpp
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
using LlvmLibcTanTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/test/src/math/tanf_test.cpp b/test/src/math/tanf_test.cpp
index 5621e819522f..d40bc44d6442 100644
--- a/test/src/math/tanf_test.cpp
+++ b/test/src/math/tanf_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/tanf.h"
@@ -13,7 +14,6 @@
#include "test/UnitTest/Test.h"
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -25,7 +25,7 @@ using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcTanfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/math/tanhf_test.cpp b/test/src/math/tanhf_test.cpp
index 862ba6cc7eeb..ef272b17d68c 100644
--- a/test/src/math/tanhf_test.cpp
+++ b/test/src/math/tanhf_test.cpp
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/math-macros.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/errno/libc_errno.h"
#include "src/math/tanhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <math.h>
#include <errno.h>
#include <stdint.h>
@@ -22,7 +22,7 @@ using LlvmLibcTanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
TEST_F(LlvmLibcTanhfTest, SpecialNumbers) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanhf(aNaN));
EXPECT_MATH_ERRNO(0);
diff --git a/test/src/sched/affinity_test.cpp b/test/src/sched/affinity_test.cpp
index 38433edecbd0..b5085203e5ce 100644
--- a/test/src/sched/affinity_test.cpp
+++ b/test/src/sched/affinity_test.cpp
@@ -17,7 +17,7 @@
TEST(LlvmLibcSchedAffinityTest, SmokeTest) {
cpu_set_t mask;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
pid_t tid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_gettid);
ASSERT_GT(tid, pid_t(0));
@@ -32,15 +32,15 @@ TEST(LlvmLibcSchedAffinityTest, BadMask) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
pid_t tid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_gettid);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(
LIBC_NAMESPACE::sched_getaffinity(tid, sizeof(cpu_set_t), nullptr),
Fails(EFAULT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(
LIBC_NAMESPACE::sched_setaffinity(tid, sizeof(cpu_set_t), nullptr),
Fails(EFAULT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sched/cpu_count_test.cpp b/test/src/sched/cpu_count_test.cpp
index ca3e80818a5c..5250368a2616 100644
--- a/test/src/sched/cpu_count_test.cpp
+++ b/test/src/sched/cpu_count_test.cpp
@@ -17,7 +17,7 @@
TEST(LlvmLibcSchedCpuCountTest, SmokeTest) {
cpu_set_t mask;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
pid_t tid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_gettid);
ASSERT_GT(tid, pid_t(0));
diff --git a/test/src/sched/get_priority_test.cpp b/test/src/sched/get_priority_test.cpp
index 4ff7890c4f40..59205c51e4a1 100644
--- a/test/src/sched/get_priority_test.cpp
+++ b/test/src/sched/get_priority_test.cpp
@@ -58,7 +58,7 @@ TEST(LlvmLibcSchedGetPriorityTest, HandleBadPolicyTest) {
}
TEST(LlvmLibcSchedGetPriorityTest, SmokeTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// We Test:
// SCHED_OTHER, SCHED_FIFO, SCHED_RR
diff --git a/test/src/sched/param_and_scheduler_test.cpp b/test/src/sched/param_and_scheduler_test.cpp
index 7fcb667a31a9..8e81f2ed1517 100644
--- a/test/src/sched/param_and_scheduler_test.cpp
+++ b/test/src/sched/param_and_scheduler_test.cpp
@@ -37,7 +37,7 @@
class SchedTest : public LIBC_NAMESPACE::testing::Test {
public:
void testSched(int policy, bool can_set) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int init_policy = LIBC_NAMESPACE::sched_getscheduler(0);
ASSERT_GE(init_policy, 0);
@@ -55,38 +55,40 @@ public:
// Negative pid
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(-1, policy, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_getscheduler(-1), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// Invalid Policy
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy | 128, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// Out of bounds priority
param.sched_priority = min_priority - 1;
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
param.sched_priority = max_priority + 1;
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, &param), -1);
// A bit hard to test as depending if we are root or not we can run into
// different issues.
- ASSERT_TRUE(libc_errno == EINVAL || libc_errno == EPERM);
- libc_errno = 0;
+ ASSERT_TRUE(LIBC_NAMESPACE::libc_errno == EINVAL ||
+ LIBC_NAMESPACE::libc_errno == EPERM);
+ LIBC_NAMESPACE::libc_errno = 0;
// Some sched policies require permissions, so skip
param.sched_priority = min_priority;
// Success / missing permissions.
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, &param),
can_set ? 0 : -1);
- ASSERT_TRUE(can_set ? (libc_errno == 0)
- : (libc_errno == EINVAL || libc_errno == EPERM));
- libc_errno = 0;
+ ASSERT_TRUE(can_set ? (LIBC_NAMESPACE::libc_errno == 0)
+ : (LIBC_NAMESPACE::libc_errno == EINVAL ||
+ LIBC_NAMESPACE::libc_errno == EPERM));
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_getscheduler(0),
can_set ? policy : init_policy);
@@ -96,12 +98,12 @@ public:
param.sched_priority = -1;
ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
param.sched_priority = max_priority + 1;
ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
for (int priority = min_priority; priority <= max_priority; ++priority) {
ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, &param), 0);
@@ -113,17 +115,18 @@ public:
// Negative pid
ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(-1, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(-1, &param), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// Success / missing permissions
ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, &param), can_set ? 0 : -1);
- ASSERT_TRUE(can_set ? (libc_errno == 0)
- : (libc_errno == EINVAL || libc_errno == EPERM));
- libc_errno = 0;
+ ASSERT_TRUE(can_set ? (LIBC_NAMESPACE::libc_errno == 0)
+ : (LIBC_NAMESPACE::libc_errno == EINVAL ||
+ LIBC_NAMESPACE::libc_errno == EPERM));
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, &param), 0);
ASSERT_ERRNO_SUCCESS();
@@ -134,7 +137,7 @@ public:
// Null test
ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, nullptr), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
};
@@ -152,13 +155,13 @@ LIST_SCHED_TESTS(SCHED_BATCH, true)
LIST_SCHED_TESTS(SCHED_IDLE, true)
TEST(LlvmLibcSchedParamAndSchedulerTest, NullParamTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, nullptr), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, nullptr), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sched/sched_rr_get_interval_test.cpp b/test/src/sched/sched_rr_get_interval_test.cpp
index 5e024f07ced1..c22a2c76d743 100644
--- a/test/src/sched/sched_rr_get_interval_test.cpp
+++ b/test/src/sched/sched_rr_get_interval_test.cpp
@@ -17,7 +17,7 @@
#include <sched.h>
TEST(LlvmLibcSchedRRGetIntervalTest, SmokeTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
auto SetSched = [&](int policy) {
int min_priority = LIBC_NAMESPACE::sched_get_priority_min(policy);
ASSERT_GE(min_priority, 0);
@@ -58,19 +58,19 @@ TEST(LlvmLibcSchedRRGetIntervalTest, SmokeTest) {
// Null timespec
ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(0, nullptr), -1);
ASSERT_ERRNO_EQ(EFAULT);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// Negative pid
ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(-1, &ts), -1);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
// Negative tests don't have SCHED_RR set
SetSched(SCHED_OTHER);
ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(0, &ts), 0);
ASSERT_ERRNO_SUCCESS();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// TODO: Missing unkown pid -> ESRCH. This is read only so safe to try a few
// unlikely values.
diff --git a/test/src/sched/yield_test.cpp b/test/src/sched/yield_test.cpp
index 5e4e07bc199b..f1627a71fa9a 100644
--- a/test/src/sched/yield_test.cpp
+++ b/test/src/sched/yield_test.cpp
@@ -11,7 +11,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcSchedYieldTest, SmokeTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// sched_yield() always succeeds, just do a basic test that errno/ret are
// properly 0.
ASSERT_EQ(LIBC_NAMESPACE::sched_yield(), 0);
diff --git a/test/src/search/insque_test.cpp b/test/src/search/insque_test.cpp
new file mode 100644
index 000000000000..8aab53c0147f
--- /dev/null
+++ b/test/src/search/insque_test.cpp
@@ -0,0 +1,186 @@
+//===-- Unittests for insque ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/search/insque.h"
+#include "src/search/remque.h"
+#include "test/UnitTest/Test.h"
+
+namespace {
+
+struct Node {
+ Node *next;
+ Node *prev;
+};
+
+template <unsigned N> void make_linear_links(Node (&nodes)[N]) {
+ for (unsigned i = 0; i < N; ++i) {
+ if (i == N - 1)
+ nodes[i].next = nullptr;
+ else
+ nodes[i].next = &nodes[i + 1];
+
+ if (i == 0)
+ nodes[i].prev = nullptr;
+ else
+ nodes[i].prev = &nodes[i - 1];
+ }
+}
+
+template <unsigned N> void make_circular_links(Node (&nodes)[N]) {
+ for (unsigned i = 0; i < N; ++i) {
+ nodes[i].next = &nodes[(i + 1) % N];
+ nodes[i].prev = &nodes[(i + N - 1) % N];
+ }
+}
+
+} // namespace
+
+class LlvmLibcInsqueTest : public LIBC_NAMESPACE::testing::Test {
+protected:
+ template <unsigned N>
+ void check_linear(const Node *head, const Node *const (&nodes)[N]) {
+ // First make sure that the given N nodes form a valid linear list.
+ for (unsigned i = 0; i < N; ++i) {
+ const Node *next = nullptr;
+ if (i + 1 < N)
+ next = nodes[i + 1];
+
+ const Node *prev = nullptr;
+ if (i > 0)
+ prev = nodes[i - 1];
+
+ EXPECT_EQ(static_cast<const Node *>(nodes[i]->next), next);
+ EXPECT_EQ(static_cast<const Node *>(nodes[i]->prev), prev);
+ }
+
+ // Then check the list nodes match.
+ for (unsigned i = 0; i < N; ++i) {
+ EXPECT_EQ(head, nodes[i]);
+ // Traversal by head should always be OK since we have already confirmed
+ // the validity of links.
+ head = head->next;
+ }
+ }
+
+ template <unsigned N>
+ void check_circular(const Node *head, const Node *const (&nodes)[N]) {
+ // First make sure that the given N nodes form a valid linear list.
+ for (unsigned i = 0; i < N; ++i) {
+ auto next = nodes[(i + 1) % N];
+ auto prev = nodes[(i + N - 1) % N];
+
+ EXPECT_EQ(static_cast<const Node *>(nodes[i]->prev), prev);
+ EXPECT_EQ(static_cast<const Node *>(nodes[i]->next), next);
+ }
+
+ // Then check the list nodes match.
+ for (unsigned i = 0; i < N; ++i) {
+ EXPECT_EQ(head, nodes[i]);
+ // Traversal by head should always be OK since we have already confirmed
+ // the validity of links.
+ head = head->next;
+ }
+ }
+};
+
+TEST_F(LlvmLibcInsqueTest, InsertToNull) {
+ Node node{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&node, nullptr);
+ check_linear(&node, {&node});
+}
+
+TEST_F(LlvmLibcInsqueTest, InsertToLinearSingleton) {
+ Node base[1];
+ make_linear_links(base);
+
+ Node incoming{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&incoming, &base[0]);
+ check_linear(base, {&base[0], &incoming});
+}
+
+TEST_F(LlvmLibcInsqueTest, InsertToLinearMiddle) {
+ Node base[3];
+ make_linear_links(base);
+
+ Node incoming{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&incoming, &base[1]);
+ check_linear(base, {&base[0], &base[1], &incoming, &base[2]});
+}
+
+TEST_F(LlvmLibcInsqueTest, InsertToLinearBack) {
+ Node base[3];
+ make_linear_links(base);
+
+ Node incoming{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&incoming, &base[2]);
+ check_linear(base, {&base[0], &base[1], &base[2], &incoming});
+}
+
+TEST_F(LlvmLibcInsqueTest, InsertToCircularSingleton) {
+ Node base[1];
+ make_circular_links(base);
+
+ Node incoming{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&incoming, &base[0]);
+ check_circular(base, {&base[0], &incoming});
+}
+
+TEST_F(LlvmLibcInsqueTest, InsertToCircular) {
+ Node base[3];
+ make_circular_links(base);
+
+ Node incoming{nullptr, nullptr};
+ LIBC_NAMESPACE::insque(&incoming, &base[1]);
+ check_circular(base, {&base[0], &base[1], &incoming, &base[2]});
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromLinearSingleton) {
+ Node node{nullptr, nullptr};
+ LIBC_NAMESPACE::remque(&node);
+ ASSERT_EQ(node.next, static_cast<Node *>(nullptr));
+ ASSERT_EQ(node.prev, static_cast<Node *>(nullptr));
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromLinearFront) {
+ Node base[3];
+ make_linear_links(base);
+
+ LIBC_NAMESPACE::remque(&base[0]);
+ check_linear(&base[1], {&base[1], &base[2]});
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromLinearMiddle) {
+ Node base[3];
+ make_linear_links(base);
+
+ LIBC_NAMESPACE::remque(&base[1]);
+ check_linear(&base[0], {&base[0], &base[2]});
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromLinearBack) {
+ Node base[3];
+ make_linear_links(base);
+
+ LIBC_NAMESPACE::remque(&base[2]);
+ check_linear(&base[0], {&base[0], &base[1]});
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromCircularSingleton) {
+ Node node[1];
+ make_circular_links(node);
+
+ LIBC_NAMESPACE::remque(&node[0]);
+}
+
+TEST_F(LlvmLibcInsqueTest, RemoveFromCircular) {
+ Node base[3];
+ make_circular_links(base);
+
+ LIBC_NAMESPACE::remque(&base[1]);
+ check_circular(&base[0], {&base[0], &base[2]});
+}
diff --git a/test/src/signal/sigaltstack_test.cpp b/test/src/signal/sigaltstack_test.cpp
index 5e1a3a4e2062..12bf2bf5e372 100644
--- a/test/src/signal/sigaltstack_test.cpp
+++ b/test/src/signal/sigaltstack_test.cpp
@@ -47,7 +47,7 @@ static void handler(int) {
TEST(LlvmLibcSignalTest, SigaltstackRunOnAltStack) {
struct sigaction action;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1, nullptr, &action),
Succeeds(0));
action.sa_handler = handler;
diff --git a/test/src/signal/signal_test.cpp b/test/src/signal/signal_test.cpp
index 78f8bfbd719b..70e95a8c159a 100644
--- a/test/src/signal/signal_test.cpp
+++ b/test/src/signal/signal_test.cpp
@@ -19,7 +19,7 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcSignal, Invalid) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::sighandler_t valid = +[](int) {};
EXPECT_THAT((void *)LIBC_NAMESPACE::signal(0, valid),
Fails(EINVAL, (void *)SIG_ERR));
diff --git a/test/src/signal/sigprocmask_test.cpp b/test/src/signal/sigprocmask_test.cpp
index 3e7e3a5c62db..12403f68b593 100644
--- a/test/src/signal/sigprocmask_test.cpp
+++ b/test/src/signal/sigprocmask_test.cpp
@@ -33,7 +33,7 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
// This tests for invalid input.
TEST_F(LlvmLibcSignalTest, SigprocmaskInvalid) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
sigset_t valid;
// 17 and -4 are out of the range for sigprocmask's how paramater.
diff --git a/test/src/stdbit/stdc_bit_ceil_uc_test.cpp b/test/src/stdbit/stdc_bit_ceil_uc_test.cpp
new file mode 100644
index 000000000000..1ef87b0d44de
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_ceil_uc_test.cpp
@@ -0,0 +1,34 @@
+//===-- Unittests for stdc_bit_ceil_uc ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_ceil_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitceilUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_uc(0U),
+ static_cast<unsigned char>(1));
+}
+
+TEST(LlvmLibcStdcBitceilUcTest, Ones) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_uc(1U << i),
+ static_cast<unsigned char>(1U << i));
+}
+
+TEST(LlvmLibcStdcBitceilUcTest, OneLessThanPowsTwo) {
+ for (unsigned i = 2U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_uc((1U << i) - 1),
+ static_cast<unsigned char>(1U << i));
+}
+
+TEST(LlvmLibcStdcBitceilUcTest, OneMoreThanPowsTwo) {
+ for (unsigned i = 1U; i != UCHAR_WIDTH - 1; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_uc((1U << i) + 1),
+ static_cast<unsigned char>(1U << (i + 1)));
+}
diff --git a/test/src/stdbit/stdc_bit_ceil_ui_test.cpp b/test/src/stdbit/stdc_bit_ceil_ui_test.cpp
new file mode 100644
index 000000000000..3b6f2a564ff1
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_ceil_ui_test.cpp
@@ -0,0 +1,30 @@
+//===-- Unittests for stdc_bit_ceil_ui ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_ceil_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitceilUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ui(0U), 1U);
+}
+
+TEST(LlvmLibcStdcBitceilUiTest, Ones) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ui(1U << i), 1U << i);
+}
+
+TEST(LlvmLibcStdcBitceilUiTest, OneLessThanPowsTwo) {
+ for (unsigned i = 2U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ui((1U << i) - 1), 1U << i);
+}
+
+TEST(LlvmLibcStdcBitceilUiTest, OneMoreThanPowsTwo) {
+ for (unsigned i = 1U; i != UINT_WIDTH - 1; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ui((1U << i) + 1), 1U << (i + 1));
+}
diff --git a/test/src/stdbit/stdc_bit_ceil_ul_test.cpp b/test/src/stdbit/stdc_bit_ceil_ul_test.cpp
new file mode 100644
index 000000000000..d4dbb38ea02a
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_ceil_ul_test.cpp
@@ -0,0 +1,30 @@
+//===-- Unittests for stdc_bit_ceil_ul ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_ceil_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitceilUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ul(0UL), 1UL);
+}
+
+TEST(LlvmLibcStdcBitceilUlTest, Ones) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ul(1UL << i), 1UL << i);
+}
+
+TEST(LlvmLibcStdcBitceilUlTest, OneLessThanPowsTwo) {
+ for (unsigned i = 2U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ul((1UL << i) - 1), 1UL << i);
+}
+
+TEST(LlvmLibcStdcBitceilUlTest, OneMoreThanPowsTwo) {
+ for (unsigned i = 1U; i != ULONG_WIDTH - 1; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ul((1UL << i) + 1), 1UL << (i + 1));
+}
diff --git a/test/src/stdbit/stdc_bit_ceil_ull_test.cpp b/test/src/stdbit/stdc_bit_ceil_ull_test.cpp
new file mode 100644
index 000000000000..762f4f0627e6
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_ceil_ull_test.cpp
@@ -0,0 +1,31 @@
+//===-- Unittests for stdc_bit_ceil_ull -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_ceil_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitceilUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ull(0ULL), 1ULL);
+}
+
+TEST(LlvmLibcStdcBitceilUllTest, Ones) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ull(1ULL << i), 1ULL << i);
+}
+
+TEST(LlvmLibcStdcBitceilUllTest, OneLessThanPowsTwo) {
+ for (unsigned i = 2U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ull((1ULL << i) - 1), 1ULL << i);
+}
+
+TEST(LlvmLibcStdcBitceilUllTest, OneMoreThanPowsTwo) {
+ for (unsigned i = 1U; i != ULLONG_WIDTH - 1; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_ull((1ULL << i) + 1),
+ 1ULL << (i + 1));
+}
diff --git a/test/src/stdbit/stdc_bit_ceil_us_test.cpp b/test/src/stdbit/stdc_bit_ceil_us_test.cpp
new file mode 100644
index 000000000000..56873c51828f
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_ceil_us_test.cpp
@@ -0,0 +1,34 @@
+//===-- Unittests for stdc_bit_ceil_us ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_ceil_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitceilUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_us(0U),
+ static_cast<unsigned short>(1));
+}
+
+TEST(LlvmLibcStdcBitceilUsTest, Ones) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_us(1U << i),
+ static_cast<unsigned short>(1U << i));
+}
+
+TEST(LlvmLibcStdcBitceilUsTest, OneLessThanPowsTwo) {
+ for (unsigned i = 2U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_us((1U << i) - 1),
+ static_cast<unsigned short>(1U << i));
+}
+
+TEST(LlvmLibcStdcBitceilUsTest, OneMoreThanPowsTwo) {
+ for (unsigned i = 1U; i != USHRT_WIDTH - 1; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_ceil_us((1U << i) + 1),
+ static_cast<unsigned short>(1U << (i + 1)));
+}
diff --git a/test/src/stdbit/stdc_bit_floor_uc_test.cpp b/test/src/stdbit/stdc_bit_floor_uc_test.cpp
new file mode 100644
index 000000000000..254abd043d6e
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_floor_uc_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_bit_floor_uc -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_floor_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitfloorUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_uc(0U),
+ static_cast<unsigned char>(0));
+}
+
+TEST(LlvmLibcStdcBitfloorUcTest, Ones) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_uc(UCHAR_MAX >> i),
+ static_cast<unsigned char>(1 << (UCHAR_WIDTH - i - 1)));
+}
diff --git a/test/src/stdbit/stdc_bit_floor_ui_test.cpp b/test/src/stdbit/stdc_bit_floor_ui_test.cpp
new file mode 100644
index 000000000000..53790402a9bd
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_floor_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_floor_ui -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_floor_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitfloorUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ui(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitfloorUiTest, Ones) {
+ for (unsigned i = 0U; i != INT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ui(UINT_MAX >> i),
+ 1U << (UINT_WIDTH - i - 1));
+}
diff --git a/test/src/stdbit/stdc_bit_floor_ul_test.cpp b/test/src/stdbit/stdc_bit_floor_ul_test.cpp
new file mode 100644
index 000000000000..1c574437e02b
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_floor_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_floor_ul -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_floor_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitfloorUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ul(0UL), 0UL);
+}
+
+TEST(LlvmLibcStdcBitfloorUlTest, Ones) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ul(ULONG_MAX >> i),
+ 1UL << (ULONG_WIDTH - i - 1));
+}
diff --git a/test/src/stdbit/stdc_bit_floor_ull_test.cpp b/test/src/stdbit/stdc_bit_floor_ull_test.cpp
new file mode 100644
index 000000000000..4717d427a40a
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_floor_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_floor_ull ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_floor_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitfloorUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ull(0ULL), 0ULL);
+}
+
+TEST(LlvmLibcStdcBitfloorUllTest, Ones) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_ull(ULLONG_MAX >> i),
+ 1ULL << (ULLONG_WIDTH - i - 1));
+}
diff --git a/test/src/stdbit/stdc_bit_floor_us_test.cpp b/test/src/stdbit/stdc_bit_floor_us_test.cpp
new file mode 100644
index 000000000000..4df87fb079ba
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_floor_us_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_bit_floor_us -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_floor_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitfloorUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_us(0U),
+ static_cast<unsigned short>(0));
+}
+
+TEST(LlvmLibcStdcBitfloorUsTest, Ones) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_floor_us(USHRT_MAX >> i),
+ static_cast<unsigned short>(1 << (USHRT_WIDTH - i - 1)));
+}
diff --git a/test/src/stdbit/stdc_bit_width_uc_test.cpp b/test/src/stdbit/stdc_bit_width_uc_test.cpp
new file mode 100644
index 000000000000..63c6503542b1
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_width_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_width_uc -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_width_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitWidthUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_uc(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitWidthUcTest, Ones) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_uc(UCHAR_MAX >> i),
+ UCHAR_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_bit_width_ui_test.cpp b/test/src/stdbit/stdc_bit_width_ui_test.cpp
new file mode 100644
index 000000000000..43acdde5dd20
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_width_ui_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_bit_width_ui -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_width_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitWidthUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ui(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitWidthUiTest, Ones) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ui(UINT_MAX >> i), UINT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_bit_width_ul_test.cpp b/test/src/stdbit/stdc_bit_width_ul_test.cpp
new file mode 100644
index 000000000000..0a286942655f
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_width_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_width_ul -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_width_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitWidthUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ul(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitWidthUlTest, Ones) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ul(ULONG_MAX >> i),
+ ULONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_bit_width_ull_test.cpp b/test/src/stdbit/stdc_bit_width_ull_test.cpp
new file mode 100644
index 000000000000..31475f6e6541
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_width_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_width_ull ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_width_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitWidthUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ull(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitWidthUllTest, Ones) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_ull(ULLONG_MAX >> i),
+ ULLONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_bit_width_us_test.cpp b/test/src/stdbit/stdc_bit_width_us_test.cpp
new file mode 100644
index 000000000000..031c502f19c5
--- /dev/null
+++ b/test/src/stdbit/stdc_bit_width_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_bit_width_us -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_bit_width_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcBitWidthUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_us(0U), 0U);
+}
+
+TEST(LlvmLibcStdcBitWidthUsTest, Ones) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_bit_width_us(USHRT_MAX >> i),
+ USHRT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_ones_uc_test.cpp b/test/src/stdbit/stdc_count_ones_uc_test.cpp
new file mode 100644
index 000000000000..791288154bae
--- /dev/null
+++ b/test/src/stdbit/stdc_count_ones_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_ones_uc ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_ones_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountOnesUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_uc(0U), 0U);
+}
+
+TEST(LlvmLibcStdcCountOnesUcTest, Ones) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_uc(UCHAR_MAX >> i),
+ UCHAR_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_ones_ui_test.cpp b/test/src/stdbit/stdc_count_ones_ui_test.cpp
new file mode 100644
index 000000000000..198e36658421
--- /dev/null
+++ b/test/src/stdbit/stdc_count_ones_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_ones_ui ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_ones_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountOnesUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ui(0), 0U);
+}
+
+TEST(LlvmLibcStdcCountOnesUiTest, Ones) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ui(UINT_MAX >> i),
+ UINT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_ones_ul_test.cpp b/test/src/stdbit/stdc_count_ones_ul_test.cpp
new file mode 100644
index 000000000000..ce9d6eb081d4
--- /dev/null
+++ b/test/src/stdbit/stdc_count_ones_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_ones_ul ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_ones_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountOnesUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ul(0UL), 0U);
+}
+
+TEST(LlvmLibcStdcCountOnesUlTest, Ones) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ul(ULONG_MAX >> i),
+ ULONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_ones_ull_test.cpp b/test/src/stdbit/stdc_count_ones_ull_test.cpp
new file mode 100644
index 000000000000..a0e69459c5a8
--- /dev/null
+++ b/test/src/stdbit/stdc_count_ones_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_ones_ull ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_ones_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountOnesUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ull(0ULL), 0U);
+}
+
+TEST(LlvmLibcStdcCountOnesUllTest, Ones) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_ull(ULLONG_MAX >> i),
+ ULLONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_ones_us_test.cpp b/test/src/stdbit/stdc_count_ones_us_test.cpp
new file mode 100644
index 000000000000..19d342606285
--- /dev/null
+++ b/test/src/stdbit/stdc_count_ones_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_ones_us ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_ones_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountOnesUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_us(0), 0U);
+}
+
+TEST(LlvmLibcStdcCountOnesUsTest, Ones) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_ones_us(USHRT_MAX >> i),
+ USHRT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_count_zeros_uc_test.cpp b/test/src/stdbit/stdc_count_zeros_uc_test.cpp
new file mode 100644
index 000000000000..3acf61aed637
--- /dev/null
+++ b/test/src/stdbit/stdc_count_zeros_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_zeros_uc ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_zeros_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountZerosUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_uc(0U),
+ static_cast<unsigned>(UCHAR_WIDTH));
+}
+
+TEST(LlvmLibcStdcCountZerosUcTest, Ones) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_uc(UCHAR_MAX >> i), i);
+}
diff --git a/test/src/stdbit/stdc_count_zeros_ui_test.cpp b/test/src/stdbit/stdc_count_zeros_ui_test.cpp
new file mode 100644
index 000000000000..53ce1c86b40f
--- /dev/null
+++ b/test/src/stdbit/stdc_count_zeros_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_zeros_ui ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_zeros_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountZerosUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ui(0U),
+ static_cast<unsigned>(UINT_WIDTH));
+}
+
+TEST(LlvmLibcStdcCountZerosUiTest, Ones) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ui(UINT_MAX >> i), i);
+}
diff --git a/test/src/stdbit/stdc_count_zeros_ul_test.cpp b/test/src/stdbit/stdc_count_zeros_ul_test.cpp
new file mode 100644
index 000000000000..60f01f316657
--- /dev/null
+++ b/test/src/stdbit/stdc_count_zeros_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_zeros_ul ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_zeros_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountZerosUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ul(0U),
+ static_cast<unsigned>(ULONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcCountZerosUlTest, Ones) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ul(ULONG_MAX >> i), i);
+}
diff --git a/test/src/stdbit/stdc_count_zeros_ull_test.cpp b/test/src/stdbit/stdc_count_zeros_ull_test.cpp
new file mode 100644
index 000000000000..7da2493c0e8f
--- /dev/null
+++ b/test/src/stdbit/stdc_count_zeros_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_zeros_ull --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_zeros_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountZerosUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ull(0U),
+ static_cast<unsigned>(ULLONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcCountZerosUllTest, Ones) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_ull(ULLONG_MAX >> i), i);
+}
diff --git a/test/src/stdbit/stdc_count_zeros_us_test.cpp b/test/src/stdbit/stdc_count_zeros_us_test.cpp
new file mode 100644
index 000000000000..e8690cb989e3
--- /dev/null
+++ b/test/src/stdbit/stdc_count_zeros_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_count_zeros_us ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_count_zeros_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcCountZerosUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_us(0U),
+ static_cast<unsigned>(USHRT_WIDTH));
+}
+
+TEST(LlvmLibcStdcCountZerosUsTest, Ones) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_count_zeros_us(USHRT_MAX >> i), i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_one_uc_test.cpp b/test/src/stdbit/stdc_first_leading_one_uc_test.cpp
new file mode 100644
index 000000000000..b8c8db587098
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_one_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_one_uc ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_one_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingOneUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_uc(0U), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingOneUcTest, OneHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_uc(1U << i),
+ UCHAR_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_one_ui_test.cpp b/test/src/stdbit/stdc_first_leading_one_ui_test.cpp
new file mode 100644
index 000000000000..319d7482c50f
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_one_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_one_ui ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_one_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingOneUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ui(0U), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingOneUiTest, OneHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ui(1U << i),
+ UINT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_one_ul_test.cpp b/test/src/stdbit/stdc_first_leading_one_ul_test.cpp
new file mode 100644
index 000000000000..5884cec418ce
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_one_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_one_ul ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_one_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingOneUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ul(0UL), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingOneUlTest, OneHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ul(1UL << i),
+ ULONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_one_ull_test.cpp b/test/src/stdbit/stdc_first_leading_one_ull_test.cpp
new file mode 100644
index 000000000000..bf57f16c1dca
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_one_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_one_ull --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_one_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingOneUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ull(0ULL), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingOneUllTest, OneHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_ull(1ULL << i),
+ ULLONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_one_us_test.cpp b/test/src/stdbit/stdc_first_leading_one_us_test.cpp
new file mode 100644
index 000000000000..e9488335d9b0
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_one_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_one_us ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_one_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingOneUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_us(0U), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingOneUsTest, OneHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_one_us(1U << i),
+ USHRT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_zero_uc_test.cpp b/test/src/stdbit/stdc_first_leading_zero_uc_test.cpp
new file mode 100644
index 000000000000..ac7e8c7d9e64
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_zero_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_zero_uc --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_zero_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingZeroUcTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_uc(UCHAR_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingZeroUcTest, ZeroHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_uc(~(1U << i)),
+ UCHAR_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_zero_ui_test.cpp b/test/src/stdbit/stdc_first_leading_zero_ui_test.cpp
new file mode 100644
index 000000000000..79a4e5394349
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_zero_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_zero_ui --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_zero_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingZeroUiTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ui(UINT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingZeroUiTest, ZeroHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ui(~(1U << i)),
+ UINT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_zero_ul_test.cpp b/test/src/stdbit/stdc_first_leading_zero_ul_test.cpp
new file mode 100644
index 000000000000..92cac6c8bffd
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_zero_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_zero_ul --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_zero_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingZeroUlTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ul(ULONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingZeroUlTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ul(~(1UL << i)),
+ ULONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_zero_ull_test.cpp b/test/src/stdbit/stdc_first_leading_zero_ull_test.cpp
new file mode 100644
index 000000000000..a5afdad591ae
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_zero_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_zero_ull -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_zero_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingZeroUllTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ull(ULLONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingZeroUllTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_ull(~(1ULL << i)),
+ ULLONG_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_leading_zero_us_test.cpp b/test/src/stdbit/stdc_first_leading_zero_us_test.cpp
new file mode 100644
index 000000000000..37f8612675a7
--- /dev/null
+++ b/test/src/stdbit/stdc_first_leading_zero_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_leading_zero_us --------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_leading_zero_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstLeadingZeroUsTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_us(USHRT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstLeadingZeroUsTest, ZeroHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_leading_zero_us(~(1U << i)),
+ USHRT_WIDTH - i);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_one_uc_test.cpp b/test/src/stdbit/stdc_first_trailing_one_uc_test.cpp
new file mode 100644
index 000000000000..ed2b4921cdad
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_one_uc_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_one_uc -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_one_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingOneUcTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_uc(UCHAR_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingOneUcTest, OneHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_uc(1U << i), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_one_ui_test.cpp b/test/src/stdbit/stdc_first_trailing_one_ui_test.cpp
new file mode 100644
index 000000000000..137c8a42e407
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_one_ui_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_one_ui -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_one_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingOneUiTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ui(UINT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingOneUiTest, OneHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ui(1U << i), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_one_ul_test.cpp b/test/src/stdbit/stdc_first_trailing_one_ul_test.cpp
new file mode 100644
index 000000000000..3fc1f3f16c60
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_one_ul_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_one_ul -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_one_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingOneUlTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ul(ULONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingOneUlTest, OneHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ul(1UL << i), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_one_ull_test.cpp b/test/src/stdbit/stdc_first_trailing_one_ull_test.cpp
new file mode 100644
index 000000000000..5719e09a5120
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_one_ull_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_one_ull ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_one_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingOneUllTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ull(ULLONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingOneUllTest, OneHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_ull(1ULL << i), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_one_us_test.cpp b/test/src/stdbit/stdc_first_trailing_one_us_test.cpp
new file mode 100644
index 000000000000..60021552310b
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_one_us_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_one_us -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_one_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingOneUsTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_us(USHRT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingOneUsTest, OneHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_one_us(1U << i), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_zero_uc_test.cpp b/test/src/stdbit/stdc_first_trailing_zero_uc_test.cpp
new file mode 100644
index 000000000000..2b17aa6536e6
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_zero_uc_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_zero_uc -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_zero_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingZeroUcTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_uc(UCHAR_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingZeroUcTest, ZeroHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_uc(~(1U << i)), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_zero_ui_test.cpp b/test/src/stdbit/stdc_first_trailing_zero_ui_test.cpp
new file mode 100644
index 000000000000..08366142e2a7
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_zero_ui_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_zero_ui -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_zero_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingZeroUiTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ui(UINT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingZeroUiTest, ZeroHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ui(~(1U << i)), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_zero_ul_test.cpp b/test/src/stdbit/stdc_first_trailing_zero_ul_test.cpp
new file mode 100644
index 000000000000..0c18cc73ffcc
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_zero_ul_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_zero_ul -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_zero_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingZeroUlTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ul(ULONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingZeroUlTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ul(~(1UL << i)), i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_zero_ull_test.cpp b/test/src/stdbit/stdc_first_trailing_zero_ull_test.cpp
new file mode 100644
index 000000000000..5dce42987e52
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_zero_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_first_trailing_zero_ull ------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_zero_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingZeroUllTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ull(ULLONG_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingZeroUllTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_ull(~(1ULL << i)),
+ i + 1);
+}
diff --git a/test/src/stdbit/stdc_first_trailing_zero_us_test.cpp b/test/src/stdbit/stdc_first_trailing_zero_us_test.cpp
new file mode 100644
index 000000000000..e370379300e4
--- /dev/null
+++ b/test/src/stdbit/stdc_first_trailing_zero_us_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_first_trailing_zero_us -------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_first_trailing_zero_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcFirstTrailingZeroUsTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_us(USHRT_MAX), 0U);
+}
+
+TEST(LlvmLibcStdcFirstTrailingZeroUsTest, ZeroHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_first_trailing_zero_us(~(1U << i)), i + 1);
+}
diff --git a/test/src/stdbit/stdc_has_single_bit_uc_test.cpp b/test/src/stdbit/stdc_has_single_bit_uc_test.cpp
new file mode 100644
index 000000000000..1bc189cf0b66
--- /dev/null
+++ b/test/src/stdbit/stdc_has_single_bit_uc_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_has_single_bit_uc ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_has_single_bit_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcHasSingleBitUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_uc(0U), false);
+}
+
+TEST(LlvmLibcStdcHasSingleBitUcTest, OneHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_uc(1U << i), true);
+}
diff --git a/test/src/stdbit/stdc_has_single_bit_ui_test.cpp b/test/src/stdbit/stdc_has_single_bit_ui_test.cpp
new file mode 100644
index 000000000000..c0b6abcf8fdc
--- /dev/null
+++ b/test/src/stdbit/stdc_has_single_bit_ui_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_has_single_bit_ui ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_has_single_bit_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcHasSingleBitUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ui(0U), false);
+}
+
+TEST(LlvmLibcStdcHasSingleBitUiTest, OneHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ui(1U << i), true);
+}
diff --git a/test/src/stdbit/stdc_has_single_bit_ul_test.cpp b/test/src/stdbit/stdc_has_single_bit_ul_test.cpp
new file mode 100644
index 000000000000..4c29fff748e9
--- /dev/null
+++ b/test/src/stdbit/stdc_has_single_bit_ul_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_has_single_bit_ul ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_has_single_bit_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcHasSingleBitUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ul(0U), false);
+}
+
+TEST(LlvmLibcStdcHasSingleBitUlTest, OneHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ul(1UL << i), true);
+}
diff --git a/test/src/stdbit/stdc_has_single_bit_ull_test.cpp b/test/src/stdbit/stdc_has_single_bit_ull_test.cpp
new file mode 100644
index 000000000000..59716468cc70
--- /dev/null
+++ b/test/src/stdbit/stdc_has_single_bit_ull_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_has_single_bit_ull -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_has_single_bit_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcHasSingleBitUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ull(0U), false);
+}
+
+TEST(LlvmLibcStdcHasSingleBitUllTest, OneHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_ull(1ULL << i), true);
+}
diff --git a/test/src/stdbit/stdc_has_single_bit_us_test.cpp b/test/src/stdbit/stdc_has_single_bit_us_test.cpp
new file mode 100644
index 000000000000..a038f6fac012
--- /dev/null
+++ b/test/src/stdbit/stdc_has_single_bit_us_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for stdc_has_single_bit_us ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_has_single_bit_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcHasSingleBitUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_us(0U), false);
+}
+
+TEST(LlvmLibcStdcHasSingleBitUsTest, OneHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_has_single_bit_us(1U << i), true);
+}
diff --git a/test/src/stdbit/stdc_leading_ones_uc_test.cpp b/test/src/stdbit/stdc_leading_ones_uc_test.cpp
new file mode 100644
index 000000000000..5d32d92e327a
--- /dev/null
+++ b/test/src/stdbit/stdc_leading_ones_uc_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_leading_ones_uc --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_leading_ones_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcLeadingOnesUcTest, All) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_uc(UCHAR_MAX),
+ static_cast<unsigned>(UCHAR_WIDTH));
+}
+
+TEST(LlvmLibcStdcLeadingOnesUcTest, ZeroHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_uc(~(1U << i)),
+ UCHAR_WIDTH - i - 1U);
+}
diff --git a/test/src/stdbit/stdc_leading_ones_ui_test.cpp b/test/src/stdbit/stdc_leading_ones_ui_test.cpp
new file mode 100644
index 000000000000..175a48b0d323
--- /dev/null
+++ b/test/src/stdbit/stdc_leading_ones_ui_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_leading_ones_ui --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_leading_ones_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcLeadingOnesUiTest, All) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ui(UINT_MAX),
+ static_cast<unsigned>(UINT_WIDTH));
+}
+
+TEST(LlvmLibcStdcLeadingOnesUiTest, ZeroHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ui(~(1U << i)),
+ UINT_WIDTH - i - 1U);
+}
diff --git a/test/src/stdbit/stdc_leading_ones_ul_test.cpp b/test/src/stdbit/stdc_leading_ones_ul_test.cpp
new file mode 100644
index 000000000000..b216f4c28acd
--- /dev/null
+++ b/test/src/stdbit/stdc_leading_ones_ul_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_leading_ones_ul --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_leading_ones_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcLeadingOnesUlTest, All) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ul(ULONG_MAX),
+ static_cast<unsigned>(ULONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcLeadingOnesUlTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ul(~(1UL << i)),
+ ULONG_WIDTH - i - 1U);
+}
diff --git a/test/src/stdbit/stdc_leading_ones_ull_test.cpp b/test/src/stdbit/stdc_leading_ones_ull_test.cpp
new file mode 100644
index 000000000000..176376665bbd
--- /dev/null
+++ b/test/src/stdbit/stdc_leading_ones_ull_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_leading_ones_ull -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_leading_ones_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcLeadingOnesUllTest, All) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ull(ULLONG_MAX),
+ static_cast<unsigned>(ULLONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcLeadingOnesUllTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_ull(~(1ULL << i)),
+ ULLONG_WIDTH - i - 1U);
+}
diff --git a/test/src/stdbit/stdc_leading_ones_us_test.cpp b/test/src/stdbit/stdc_leading_ones_us_test.cpp
new file mode 100644
index 000000000000..91a125370ec1
--- /dev/null
+++ b/test/src/stdbit/stdc_leading_ones_us_test.cpp
@@ -0,0 +1,22 @@
+//===-- Unittests for stdc_leading_ones_us --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_leading_ones_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcLeadingOnesUsTest, All) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_us(USHRT_MAX),
+ static_cast<unsigned>(USHRT_WIDTH));
+}
+
+TEST(LlvmLibcStdcLeadingOnesUsTest, ZeroHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_ones_us(~(1U << i)),
+ USHRT_WIDTH - i - 1U);
+}
diff --git a/test/src/stdbit/stdc_leading_zeros_uc_test.cpp b/test/src/stdbit/stdc_leading_zeros_uc_test.cpp
index 4e2e1db3bd72..3d555072927a 100644
--- a/test/src/stdbit/stdc_leading_zeros_uc_test.cpp
+++ b/test/src/stdbit/stdc_leading_zeros_uc_test.cpp
@@ -12,11 +12,11 @@
TEST(LlvmLibcStdcLeadingZerosUcTest, Zero) {
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_uc(0U),
- static_cast<unsigned char>(UCHAR_WIDTH));
+ static_cast<unsigned>(UCHAR_WIDTH));
}
TEST(LlvmLibcStdcLeadingZerosUcTest, OneHot) {
for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_uc(1U << i),
- static_cast<unsigned char>(UCHAR_WIDTH - i - 1));
+ UCHAR_WIDTH - i - 1U);
}
diff --git a/test/src/stdbit/stdc_leading_zeros_ul_test.cpp b/test/src/stdbit/stdc_leading_zeros_ul_test.cpp
index 9a73aece89ac..fd82cef548b6 100644
--- a/test/src/stdbit/stdc_leading_zeros_ul_test.cpp
+++ b/test/src/stdbit/stdc_leading_zeros_ul_test.cpp
@@ -13,11 +13,11 @@
TEST(LlvmLibcStdcLeadingZerosUlTest, Zero) {
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_ul(0UL),
- static_cast<unsigned long>(ULONG_WIDTH));
+ static_cast<unsigned>(ULONG_WIDTH));
}
TEST(LlvmLibcStdcLeadingZerosUlTest, OneHot) {
for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_ul(1UL << i),
- static_cast<unsigned long>(ULONG_WIDTH - i - 1));
+ ULONG_WIDTH - i - 1U);
}
diff --git a/test/src/stdbit/stdc_leading_zeros_ull_test.cpp b/test/src/stdbit/stdc_leading_zeros_ull_test.cpp
index 9df2f015f9b6..cdeeb3032300 100644
--- a/test/src/stdbit/stdc_leading_zeros_ull_test.cpp
+++ b/test/src/stdbit/stdc_leading_zeros_ull_test.cpp
@@ -13,11 +13,11 @@
TEST(LlvmLibcStdcLeadingZerosUllTest, Zero) {
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_ull(0ULL),
- static_cast<unsigned long long>(ULLONG_WIDTH));
+ static_cast<unsigned>(ULLONG_WIDTH));
}
TEST(LlvmLibcStdcLeadingZerosUllTest, OneHot) {
for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_ull(1ULL << i),
- static_cast<unsigned long long>(ULLONG_WIDTH - i - 1));
+ ULLONG_WIDTH - i - 1U);
}
diff --git a/test/src/stdbit/stdc_leading_zeros_us_test.cpp b/test/src/stdbit/stdc_leading_zeros_us_test.cpp
index b396a740e43b..afb418a24ad5 100644
--- a/test/src/stdbit/stdc_leading_zeros_us_test.cpp
+++ b/test/src/stdbit/stdc_leading_zeros_us_test.cpp
@@ -12,11 +12,11 @@
TEST(LlvmLibcStdcLeadingZerosUsTest, Zero) {
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_us(0U),
- static_cast<unsigned short>(USHRT_WIDTH));
+ static_cast<unsigned>(USHRT_WIDTH));
}
TEST(LlvmLibcStdcLeadingZerosUsTest, OneHot) {
for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
EXPECT_EQ(LIBC_NAMESPACE::stdc_leading_zeros_us(1U << i),
- static_cast<unsigned short>(USHRT_WIDTH - i - 1));
+ USHRT_WIDTH - i - 1U);
}
diff --git a/test/src/stdbit/stdc_trailing_ones_uc_test.cpp b/test/src/stdbit/stdc_trailing_ones_uc_test.cpp
new file mode 100644
index 000000000000..79d4e5b8b803
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_ones_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_ones_uc -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_ones_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingOnesUcTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_uc(UCHAR_MAX),
+ static_cast<unsigned>(UCHAR_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingOnesUcTest, ZeroHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_uc(~(1U << i)), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_ones_ui_test.cpp b/test/src/stdbit/stdc_trailing_ones_ui_test.cpp
new file mode 100644
index 000000000000..51e49f1e9e5f
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_ones_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_ones_ui -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_ones_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingOnesUiTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ui(UINT_MAX),
+ static_cast<unsigned>(UINT_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingOnesUiTest, ZeroHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ui(~(1U << i)), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_ones_ul_test.cpp b/test/src/stdbit/stdc_trailing_ones_ul_test.cpp
new file mode 100644
index 000000000000..2aebe2e814ca
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_ones_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_ones_ul -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_ones_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingOnesUlTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ul(ULONG_MAX),
+ static_cast<unsigned>(ULONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingOnesUlTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ul(~(1UL << i)), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_ones_ull_test.cpp b/test/src/stdbit/stdc_trailing_ones_ull_test.cpp
new file mode 100644
index 000000000000..38c5100efc06
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_ones_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_ones_ull ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_ones_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingOnesUllTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ull(ULLONG_MAX),
+ static_cast<unsigned>(ULLONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingOnesUllTest, ZeroHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_ull(~(1ULL << i)), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_ones_us_test.cpp b/test/src/stdbit/stdc_trailing_ones_us_test.cpp
new file mode 100644
index 000000000000..7ab15743ed1e
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_ones_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_ones_us -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_ones_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingOnesUsTest, ALL) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_us(USHRT_MAX),
+ static_cast<unsigned>(USHRT_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingOnesUsTest, ZeroHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_ones_us(~(1U << i)), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_zeros_uc_test.cpp b/test/src/stdbit/stdc_trailing_zeros_uc_test.cpp
new file mode 100644
index 000000000000..c02b518865d9
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_zeros_uc_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_zeros_uc ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_zeros_uc.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingZerosUcTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_uc(0U),
+ static_cast<unsigned>(UCHAR_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingZerosUcTest, OneHot) {
+ for (unsigned i = 0U; i != UCHAR_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_uc(1U << i), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_zeros_ui_test.cpp b/test/src/stdbit/stdc_trailing_zeros_ui_test.cpp
new file mode 100644
index 000000000000..ad9b12633517
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_zeros_ui_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_zeros_ui ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_zeros_ui.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingZerosUiTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ui(0U),
+ static_cast<unsigned>(UINT_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingZerosUiTest, OneHot) {
+ for (unsigned i = 0U; i != UINT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ui(1U << i), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_zeros_ul_test.cpp b/test/src/stdbit/stdc_trailing_zeros_ul_test.cpp
new file mode 100644
index 000000000000..6d7f4b3cb093
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_zeros_ul_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_zeros_ul ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_zeros_ul.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingZerosUlTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ul(0U),
+ static_cast<unsigned>(ULONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingZerosUlTest, OneHot) {
+ for (unsigned i = 0U; i != ULONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ul(1UL << i), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_zeros_ull_test.cpp b/test/src/stdbit/stdc_trailing_zeros_ull_test.cpp
new file mode 100644
index 000000000000..64b93b12e605
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_zeros_ull_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_zeros_ull -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_zeros_ull.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingZerosUllTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ull(0U),
+ static_cast<unsigned>(ULLONG_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingZerosUllTest, OneHot) {
+ for (unsigned i = 0U; i != ULLONG_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_ull(1ULL << i), i);
+}
diff --git a/test/src/stdbit/stdc_trailing_zeros_us_test.cpp b/test/src/stdbit/stdc_trailing_zeros_us_test.cpp
new file mode 100644
index 000000000000..a9f8327dfd91
--- /dev/null
+++ b/test/src/stdbit/stdc_trailing_zeros_us_test.cpp
@@ -0,0 +1,21 @@
+//===-- Unittests for stdc_trailing_zeros_us ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/CPP/limits.h"
+#include "src/stdbit/stdc_trailing_zeros_us.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStdcTrailingZerosUsTest, Zero) {
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_us(0U),
+ static_cast<unsigned>(USHRT_WIDTH));
+}
+
+TEST(LlvmLibcStdcTrailingZerosUsTest, OneHot) {
+ for (unsigned i = 0U; i != USHRT_WIDTH; ++i)
+ EXPECT_EQ(LIBC_NAMESPACE::stdc_trailing_zeros_us(1U << i), i);
+}
diff --git a/test/src/stdfix/AbsTest.h b/test/src/stdfix/AbsTest.h
new file mode 100644
index 000000000000..3d23a475720c
--- /dev/null
+++ b/test/src/stdfix/AbsTest.h
@@ -0,0 +1,37 @@
+//===-- Utility class to test fixed-point abs -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/fixed_point/fx_rep.h"
+
+template <typename T> class AbsTest : public LIBC_NAMESPACE::testing::Test {
+
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+ static constexpr T zero = FXRep::ZERO();
+ static constexpr T min = FXRep::MIN();
+ static constexpr T max = FXRep::MAX();
+ static constexpr T half = static_cast<T>(0.5);
+ static constexpr T neg_half = static_cast<T>(-0.5);
+
+public:
+ typedef T (*AbsFunc)(T);
+
+ void testSpecialNumbers(AbsFunc func) {
+ EXPECT_EQ(zero, func(zero));
+ EXPECT_EQ(max, func(min));
+ EXPECT_EQ(max, func(max));
+ EXPECT_EQ(half, func(half));
+ EXPECT_EQ(half, func(neg_half));
+ }
+};
+
+#define LIST_ABS_TESTS(T, func) \
+ using LlvmLibcAbsTest = AbsTest<T>; \
+ TEST_F(LlvmLibcAbsTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/stdfix/ExpTest.h b/test/src/stdfix/ExpTest.h
new file mode 100644
index 000000000000..e588cebf621b
--- /dev/null
+++ b/test/src/stdfix/ExpTest.h
@@ -0,0 +1,77 @@
+//===-- Utility class to test integer sqrt ----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+#include "src/math/exp.h"
+
+template <typename T> class ExpTest : public LIBC_NAMESPACE::testing::Test {
+
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+ static constexpr T zero = FXRep::ZERO();
+ static constexpr T one = static_cast<T>(1);
+ static constexpr T eps = FXRep::EPS();
+
+public:
+ typedef T (*ExpFunc)(T);
+
+ void test_special_numbers(ExpFunc func) {
+ EXPECT_EQ(one, func(T(0)));
+ EXPECT_EQ(FXRep::MAX(), func(T(30)));
+ EXPECT_EQ(zero, func(T(-30)));
+ }
+
+ void test_range_with_step(ExpFunc func, T step, bool rel_error) {
+ constexpr int COUNT = 255;
+ constexpr double ERR = 3.0 * static_cast<double>(eps);
+ double x_d = 0.0;
+ T x = step;
+ for (int i = 0; i < COUNT; ++i) {
+ x += step;
+ x_d = static_cast<double>(x);
+ double y_d = static_cast<double>(func(x));
+ double result = LIBC_NAMESPACE::exp(x_d);
+ double errors = rel_error
+ ? LIBC_NAMESPACE::fputil::abs((y_d / result) - 1.0)
+ : LIBC_NAMESPACE::fputil::abs(y_d - result);
+ if (errors > ERR) {
+ // Print out the failure input and output.
+ EXPECT_EQ(x, T(0));
+ EXPECT_EQ(func(x), zero);
+ }
+ ASSERT_TRUE(errors <= ERR);
+ }
+ }
+
+ void test_positive_range(ExpFunc func) {
+ test_range_with_step(func, T(0x1.0p-6), /*rel_error*/ true);
+ }
+
+ void test_negative_range(ExpFunc func) {
+ test_range_with_step(func, T(-0x1.0p-6), /*rel_error*/ false);
+ }
+};
+
+#define LIST_EXP_TESTS(Name, T, func) \
+ using LlvmLibcExp##Name##Test = ExpTest<T>; \
+ TEST_F(LlvmLibcExp##Name##Test, SpecialNumbers) { \
+ test_special_numbers(&func); \
+ } \
+ TEST_F(LlvmLibcExp##Name##Test, PositiveRange) { \
+ test_positive_range(&func); \
+ } \
+ TEST_F(LlvmLibcExp##Name##Test, NegativeRange) { \
+ test_negative_range(&func); \
+ } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/stdfix/ISqrtTest.h b/test/src/stdfix/ISqrtTest.h
new file mode 100644
index 000000000000..405162b706a9
--- /dev/null
+++ b/test/src/stdfix/ISqrtTest.h
@@ -0,0 +1,63 @@
+//===-- Utility class to test integer sqrt ----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+template <typename T> class ISqrtTest : public LIBC_NAMESPACE::testing::Test {
+
+ using OutType =
+ typename LIBC_NAMESPACE::fixed_point::internal::SqrtConfig<T>::OutType;
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<OutType>;
+ static constexpr OutType zero = FXRep::ZERO();
+ static constexpr OutType one = static_cast<OutType>(1);
+ static constexpr OutType eps = FXRep::EPS();
+
+public:
+ typedef OutType (*SqrtFunc)(T);
+
+ void testSpecialNumbers(SqrtFunc func) {
+ EXPECT_EQ(zero, func(T(0)));
+
+ EXPECT_EQ(one, func(T(1)));
+ EXPECT_EQ(static_cast<OutType>(2.0), func(T(4)));
+ EXPECT_EQ(static_cast<OutType>(4.0), func(T(16)));
+ EXPECT_EQ(static_cast<OutType>(16.0), func(T(256)));
+
+ constexpr int COUNT = 255;
+ constexpr double ERR = 3.0 * static_cast<double>(eps);
+ double x_d = 0.0;
+ T x = 0;
+ for (int i = 0; i < COUNT; ++i) {
+ x_d += 1.0;
+ ++x;
+ double y_d = static_cast<double>(func(x));
+ double result = LIBC_NAMESPACE::fputil::sqrt(x_d);
+ double errors = LIBC_NAMESPACE::fputil::abs((y_d / result) - 1.0);
+ if (errors > ERR) {
+ // Print out the failure input and output.
+ EXPECT_EQ(x, T(0));
+ EXPECT_EQ(func(x), zero);
+ }
+ ASSERT_TRUE(errors <= ERR);
+ }
+ }
+};
+
+#define LIST_ISQRT_TESTS(Name, T, func) \
+ using LlvmLibcISqrt##Name##Test = ISqrtTest<T>; \
+ TEST_F(LlvmLibcISqrt##Name##Test, SpecialNumbers) { \
+ testSpecialNumbers(&func); \
+ } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/stdfix/RoundTest.h b/test/src/stdfix/RoundTest.h
new file mode 100644
index 000000000000..d3ae04db9749
--- /dev/null
+++ b/test/src/stdfix/RoundTest.h
@@ -0,0 +1,65 @@
+//===-- Utility class to test fixed-point round -----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/fixed_point/fx_rep.h"
+
+template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
+
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+ static constexpr T zero = FXRep::ZERO();
+ static constexpr T min = FXRep::MIN();
+ static constexpr T max = FXRep::MAX();
+ static constexpr T half = static_cast<T>(0.5);
+ static constexpr T neg_half = static_cast<T>(-0.5);
+ static constexpr T one =
+ (FXRep::INTEGRAL_LEN > 0) ? static_cast<T>(1) : FXRep::MAX();
+ static constexpr T neg_one = static_cast<T>(-1);
+ static constexpr T eps = FXRep::EPS();
+
+public:
+ typedef T (*RoundFunc)(T, int);
+
+ void testSpecialNumbers(RoundFunc func) {
+ EXPECT_EQ(zero, func(zero, FXRep::FRACTION_LEN - 5));
+ EXPECT_EQ(min, func(min, 0));
+ EXPECT_EQ(max, func(max, FXRep::FRACTION_LEN));
+
+ EXPECT_EQ(one, func(half, 0));
+ EXPECT_EQ(half, func(half, 1));
+ EXPECT_EQ(half, func(half, FXRep::FRACTION_LEN));
+ EXPECT_EQ(one, func(half + eps, 0));
+ EXPECT_EQ(half, func(half + eps, 1));
+ EXPECT_EQ(half, func(half + eps, 2));
+ EXPECT_EQ(zero, func(half - eps, 0));
+ EXPECT_EQ(half, func(half - eps, 1));
+ EXPECT_EQ(half, func(half - eps, 2));
+ EXPECT_EQ(eps, func(eps, FXRep::FRACTION_LEN + 10));
+ EXPECT_EQ(eps << 1, func(eps, FXRep::FRACTION_LEN - 1));
+ EXPECT_EQ(zero, func(eps, FXRep::FRACTION_LEN - 2));
+
+ if constexpr (FXRep::SIGN_LEN) {
+ EXPECT_EQ(zero, func(neg_half, 0));
+ EXPECT_EQ(neg_half, func(neg_half, 1));
+ EXPECT_EQ(neg_half, func(neg_half, 3));
+ EXPECT_EQ(zero, func(neg_half + eps, 0));
+ EXPECT_EQ(neg_half, func(neg_half + eps, 1));
+ EXPECT_EQ(neg_half, func(neg_half + eps, 2));
+ EXPECT_EQ(neg_one, func(neg_half - eps, 0));
+ EXPECT_EQ(neg_half, func(neg_half - eps, 1));
+ EXPECT_EQ(neg_half, func(neg_half - eps, 2));
+ EXPECT_EQ(-eps, func(-eps, FXRep::FRACTION_LEN + 10));
+ }
+ }
+};
+
+#define LIST_ROUND_TESTS(T, func) \
+ using LlvmLibcRoundTest = RoundTest<T>; \
+ TEST_F(LlvmLibcRoundTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/stdfix/SqrtTest.h b/test/src/stdfix/SqrtTest.h
new file mode 100644
index 000000000000..628be0deb770
--- /dev/null
+++ b/test/src/stdfix/SqrtTest.h
@@ -0,0 +1,66 @@
+//===-- Utility class to test fixed-point sqrt ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/fixed_point/sqrt.h"
+
+template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
+
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+ static constexpr T zero = FXRep::ZERO();
+ static constexpr T min = FXRep::MIN();
+ static constexpr T max = FXRep::MAX();
+ static constexpr T half = static_cast<T>(0.5);
+ static constexpr T quarter = static_cast<T>(0.25);
+ static constexpr T one =
+ (FXRep::INTEGRAL_LEN > 0) ? static_cast<T>(1) : FXRep::MAX();
+ static constexpr T eps = FXRep::EPS();
+
+public:
+ typedef T (*SqrtFunc)(T);
+
+ void testSpecialNumbers(SqrtFunc func) {
+ EXPECT_EQ(zero, func(zero));
+ EXPECT_EQ(half, func(quarter));
+
+ if constexpr (FXRep::INTEGRAL_LEN) {
+ EXPECT_EQ(one, func(one));
+ EXPECT_EQ(static_cast<T>(2.0), func(static_cast<T>(4.0)));
+ }
+
+ using StorageType = typename FXRep::StorageType;
+
+ constexpr size_t COUNT = 255;
+ constexpr StorageType STEP =
+ ~StorageType(0) / static_cast<StorageType>(COUNT);
+ constexpr double ERR = 3.0 * static_cast<double>(eps);
+ StorageType x = 0;
+ for (size_t i = 0; i < COUNT; ++i, x += STEP) {
+ T v = LIBC_NAMESPACE::cpp::bit_cast<T>(x);
+ double v_d = static_cast<double>(v);
+ double errors = LIBC_NAMESPACE::fputil::abs(
+ static_cast<double>(func(v)) - LIBC_NAMESPACE::fputil::sqrt(v_d));
+ if (errors > ERR) {
+ // Print out the failure input and output.
+ EXPECT_EQ(v, zero);
+ EXPECT_EQ(func(v), zero);
+ }
+ ASSERT_TRUE(errors <= ERR);
+ }
+ }
+};
+
+#define LIST_SQRT_TESTS(T, func) \
+ using LlvmLibcSqrtTest = SqrtTest<T>; \
+ TEST_F(LlvmLibcSqrtTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/test/src/stdfix/abshk_test.cpp b/test/src/stdfix/abshk_test.cpp
new file mode 100644
index 000000000000..c3f58625ac58
--- /dev/null
+++ b/test/src/stdfix/abshk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for abshk -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/abshk.h"
+
+LIST_ABS_TESTS(short accum, LIBC_NAMESPACE::abshk);
diff --git a/test/src/stdfix/abshr_test.cpp b/test/src/stdfix/abshr_test.cpp
new file mode 100644
index 000000000000..d7a962ea1f98
--- /dev/null
+++ b/test/src/stdfix/abshr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for abshr -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/abshr.h"
+
+LIST_ABS_TESTS(short fract, LIBC_NAMESPACE::abshr);
diff --git a/test/src/stdfix/absk_test.cpp b/test/src/stdfix/absk_test.cpp
new file mode 100644
index 000000000000..729cf143a413
--- /dev/null
+++ b/test/src/stdfix/absk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for absk ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/absk.h"
+
+LIST_ABS_TESTS(accum, LIBC_NAMESPACE::absk);
diff --git a/test/src/stdfix/abslk_test.cpp b/test/src/stdfix/abslk_test.cpp
new file mode 100644
index 000000000000..93ef3469a225
--- /dev/null
+++ b/test/src/stdfix/abslk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for abslk -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/abslk.h"
+
+LIST_ABS_TESTS(long accum, LIBC_NAMESPACE::abslk);
diff --git a/test/src/stdfix/abslr_test.cpp b/test/src/stdfix/abslr_test.cpp
new file mode 100644
index 000000000000..c50a55873802
--- /dev/null
+++ b/test/src/stdfix/abslr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for abslr -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/abslr.h"
+
+LIST_ABS_TESTS(long fract, LIBC_NAMESPACE::abslr);
diff --git a/test/src/stdfix/absr_test.cpp b/test/src/stdfix/absr_test.cpp
new file mode 100644
index 000000000000..7b8117353979
--- /dev/null
+++ b/test/src/stdfix/absr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for absr ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "AbsTest.h"
+
+#include "src/stdfix/absr.h"
+
+LIST_ABS_TESTS(fract, LIBC_NAMESPACE::absr);
diff --git a/test/src/stdfix/exphk_test.cpp b/test/src/stdfix/exphk_test.cpp
new file mode 100644
index 000000000000..24e92dc902fa
--- /dev/null
+++ b/test/src/stdfix/exphk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for exphk -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "ExpTest.h"
+
+#include "src/stdfix/exphk.h"
+
+LIST_EXP_TESTS(hk, short accum, LIBC_NAMESPACE::exphk);
diff --git a/test/src/stdfix/expk_test.cpp b/test/src/stdfix/expk_test.cpp
new file mode 100644
index 000000000000..bc322037af04
--- /dev/null
+++ b/test/src/stdfix/expk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for expk ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "ExpTest.h"
+
+#include "src/stdfix/expk.h"
+
+LIST_EXP_TESTS(k, accum, LIBC_NAMESPACE::expk);
diff --git a/test/src/stdfix/roundhk_test.cpp b/test/src/stdfix/roundhk_test.cpp
new file mode 100644
index 000000000000..3cbcfb0e2b1e
--- /dev/null
+++ b/test/src/stdfix/roundhk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundhk ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundhk.h"
+
+LIST_ROUND_TESTS(short accum, LIBC_NAMESPACE::roundhk);
diff --git a/test/src/stdfix/roundhr_test.cpp b/test/src/stdfix/roundhr_test.cpp
new file mode 100644
index 000000000000..9e58fb5b2906
--- /dev/null
+++ b/test/src/stdfix/roundhr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundhr ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundhr.h"
+
+LIST_ROUND_TESTS(short fract, LIBC_NAMESPACE::roundhr);
diff --git a/test/src/stdfix/roundk_test.cpp b/test/src/stdfix/roundk_test.cpp
new file mode 100644
index 000000000000..4092ce3c6f63
--- /dev/null
+++ b/test/src/stdfix/roundk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundk ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundk.h"
+
+LIST_ROUND_TESTS(accum, LIBC_NAMESPACE::roundk);
diff --git a/test/src/stdfix/roundlk_test.cpp b/test/src/stdfix/roundlk_test.cpp
new file mode 100644
index 000000000000..c8bd1c9cb7ec
--- /dev/null
+++ b/test/src/stdfix/roundlk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundlk ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundlk.h"
+
+LIST_ROUND_TESTS(long accum, LIBC_NAMESPACE::roundlk);
diff --git a/test/src/stdfix/roundlr_test.cpp b/test/src/stdfix/roundlr_test.cpp
new file mode 100644
index 000000000000..53bfbb8fc6a0
--- /dev/null
+++ b/test/src/stdfix/roundlr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundlr ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundlr.h"
+
+LIST_ROUND_TESTS(long fract, LIBC_NAMESPACE::roundlr);
diff --git a/test/src/stdfix/roundr_test.cpp b/test/src/stdfix/roundr_test.cpp
new file mode 100644
index 000000000000..68527f1fa140
--- /dev/null
+++ b/test/src/stdfix/roundr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundr ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundr.h"
+
+LIST_ROUND_TESTS(fract, LIBC_NAMESPACE::roundr);
diff --git a/test/src/stdfix/rounduhk_test.cpp b/test/src/stdfix/rounduhk_test.cpp
new file mode 100644
index 000000000000..d03774b68155
--- /dev/null
+++ b/test/src/stdfix/rounduhk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for rounduhk --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/rounduhk.h"
+
+LIST_ROUND_TESTS(unsigned short accum, LIBC_NAMESPACE::rounduhk);
diff --git a/test/src/stdfix/rounduhr_test.cpp b/test/src/stdfix/rounduhr_test.cpp
new file mode 100644
index 000000000000..889827c3349e
--- /dev/null
+++ b/test/src/stdfix/rounduhr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for rounduhr --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/rounduhr.h"
+
+LIST_ROUND_TESTS(unsigned short fract, LIBC_NAMESPACE::rounduhr);
diff --git a/test/src/stdfix/rounduk_test.cpp b/test/src/stdfix/rounduk_test.cpp
new file mode 100644
index 000000000000..fbf73d5844f1
--- /dev/null
+++ b/test/src/stdfix/rounduk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for rounduk ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/rounduk.h"
+
+LIST_ROUND_TESTS(unsigned accum, LIBC_NAMESPACE::rounduk);
diff --git a/test/src/stdfix/roundulk_test.cpp b/test/src/stdfix/roundulk_test.cpp
new file mode 100644
index 000000000000..92db54e186c8
--- /dev/null
+++ b/test/src/stdfix/roundulk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundulk --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundulk.h"
+
+LIST_ROUND_TESTS(unsigned long accum, LIBC_NAMESPACE::roundulk);
diff --git a/test/src/stdfix/roundulr_test.cpp b/test/src/stdfix/roundulr_test.cpp
new file mode 100644
index 000000000000..11cbb46263ae
--- /dev/null
+++ b/test/src/stdfix/roundulr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundulr --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundulr.h"
+
+LIST_ROUND_TESTS(unsigned long fract, LIBC_NAMESPACE::roundulr);
diff --git a/test/src/stdfix/roundur_test.cpp b/test/src/stdfix/roundur_test.cpp
new file mode 100644
index 000000000000..636f3482cdae
--- /dev/null
+++ b/test/src/stdfix/roundur_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundur ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/stdfix/roundur.h"
+
+LIST_ROUND_TESTS(unsigned fract, LIBC_NAMESPACE::roundur);
diff --git a/test/src/stdfix/sqrtuhk_test.cpp b/test/src/stdfix/sqrtuhk_test.cpp
new file mode 100644
index 000000000000..d6ff5385cab8
--- /dev/null
+++ b/test/src/stdfix/sqrtuhk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for sqrtuhk ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "SqrtTest.h"
+
+#include "src/stdfix/sqrtuhk.h"
+
+LIST_SQRT_TESTS(unsigned short accum, LIBC_NAMESPACE::sqrtuhk);
diff --git a/test/src/stdfix/sqrtuhr_test.cpp b/test/src/stdfix/sqrtuhr_test.cpp
new file mode 100644
index 000000000000..22f00a4231b3
--- /dev/null
+++ b/test/src/stdfix/sqrtuhr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for sqrtuhr ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "SqrtTest.h"
+
+#include "src/stdfix/sqrtuhr.h"
+
+LIST_SQRT_TESTS(unsigned short fract, LIBC_NAMESPACE::sqrtuhr);
diff --git a/test/src/stdfix/sqrtuk_test.cpp b/test/src/stdfix/sqrtuk_test.cpp
new file mode 100644
index 000000000000..5a3105de1e0b
--- /dev/null
+++ b/test/src/stdfix/sqrtuk_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for sqrtuk ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "SqrtTest.h"
+
+#include "src/stdfix/sqrtuk.h"
+
+LIST_SQRT_TESTS(unsigned accum, LIBC_NAMESPACE::sqrtuk);
diff --git a/test/src/stdfix/sqrtulr_test.cpp b/test/src/stdfix/sqrtulr_test.cpp
new file mode 100644
index 000000000000..1be4e2b5e0a6
--- /dev/null
+++ b/test/src/stdfix/sqrtulr_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for sqrtulr ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "SqrtTest.h"
+
+#include "src/stdfix/sqrtulr.h"
+
+LIST_SQRT_TESTS(unsigned long fract, LIBC_NAMESPACE::sqrtulr);
diff --git a/test/src/stdfix/sqrtur_test.cpp b/test/src/stdfix/sqrtur_test.cpp
new file mode 100644
index 000000000000..12b1c2211db0
--- /dev/null
+++ b/test/src/stdfix/sqrtur_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for sqrtur ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "SqrtTest.h"
+
+#include "src/stdfix/sqrtur.h"
+
+LIST_SQRT_TESTS(unsigned fract, LIBC_NAMESPACE::sqrtur);
diff --git a/test/src/stdfix/uhksqrtus_test.cpp b/test/src/stdfix/uhksqrtus_test.cpp
new file mode 100644
index 000000000000..a33297413980
--- /dev/null
+++ b/test/src/stdfix/uhksqrtus_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for uhksqrtus -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "ISqrtTest.h"
+
+#include "src/__support/fixed_point/sqrt.h"
+#include "src/stdfix/uhksqrtus.h"
+
+unsigned short accum uhksqrtus_fast(unsigned short x) {
+ return LIBC_NAMESPACE::fixed_point::isqrt_fast(x);
+}
+
+LIST_ISQRT_TESTS(US, unsigned short, LIBC_NAMESPACE::uhksqrtus);
+
+LIST_ISQRT_TESTS(USFast, unsigned short, uhksqrtus_fast);
diff --git a/test/src/stdfix/uksqrtui_test.cpp b/test/src/stdfix/uksqrtui_test.cpp
new file mode 100644
index 000000000000..0f4c057099da
--- /dev/null
+++ b/test/src/stdfix/uksqrtui_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for uksqrtui --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "ISqrtTest.h"
+
+#include "src/__support/fixed_point/sqrt.h"
+#include "src/stdfix/uksqrtui.h"
+
+unsigned accum uksqrtui_fast(unsigned int x) {
+ return LIBC_NAMESPACE::fixed_point::isqrt_fast(x);
+}
+
+LIST_ISQRT_TESTS(UI, unsigned int, LIBC_NAMESPACE::uksqrtui);
+
+LIST_ISQRT_TESTS(UIFast, unsigned int, uksqrtui_fast);
diff --git a/test/src/stdio/fgetc_test.cpp b/test/src/stdio/fgetc_test.cpp
index 6e6c0ed9b26b..989bb312afad 100644
--- a/test/src/stdio/fgetc_test.cpp
+++ b/test/src/stdio/fgetc_test.cpp
@@ -33,7 +33,7 @@ public:
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
diff --git a/test/src/stdio/fgetc_unlocked_test.cpp b/test/src/stdio/fgetc_unlocked_test.cpp
index 0d704ecee750..48d7a043cad7 100644
--- a/test/src/stdio/fgetc_unlocked_test.cpp
+++ b/test/src/stdio/fgetc_unlocked_test.cpp
@@ -36,7 +36,7 @@ public:
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
diff --git a/test/src/stdio/fgets_test.cpp b/test/src/stdio/fgets_test.cpp
index aab8bae3d97e..d005a71710d2 100644
--- a/test/src/stdio/fgets_test.cpp
+++ b/test/src/stdio/fgets_test.cpp
@@ -36,7 +36,7 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
diff --git a/test/src/stdio/fileop_test.cpp b/test/src/stdio/fileop_test.cpp
index d620aa076ef0..0fbe19cf08d8 100644
--- a/test/src/stdio/fileop_test.cpp
+++ b/test/src/stdio/fileop_test.cpp
@@ -11,6 +11,7 @@
#include "src/stdio/feof.h"
#include "src/stdio/ferror.h"
#include "src/stdio/fflush.h"
+#include "src/stdio/fileno.h"
#include "src/stdio/fopen.h"
#include "src/stdio/fputs.h"
#include "src/stdio/fread.h"
@@ -30,6 +31,7 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
constexpr char FILENAME[] = "testdata/simple_operations.test";
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
+ ASSERT_EQ(LIBC_NAMESPACE::fileno(file), 3);
constexpr char CONTENT[] = "1234567890987654321";
ASSERT_EQ(sizeof(CONTENT) - 1,
LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT) - 1, file));
@@ -39,7 +41,7 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
ASSERT_THAT(LIBC_NAMESPACE::fread(read_data, 1, sizeof(CONTENT), file),
returns(EQ(size_t(0))).with_errno(NE(0)));
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(file);
ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);
@@ -70,7 +72,7 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), file),
returns(EQ(size_t(0))).with_errno(NE(0)));
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(file);
@@ -78,15 +80,15 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
ASSERT_THAT(LIBC_NAMESPACE::fputs(CONTENT, file),
returns(EQ(EOF)).with_errno(NE(0)));
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(file);
ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::fwrite("nothing", 1, 1, file),
returns(EQ(0)).with_errno(NE(0)));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);
@@ -101,10 +103,10 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);
// This is not a readable file.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::fread(data, 1, 1, file),
returns(EQ(0)).with_errno(NE(0)));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
@@ -119,15 +121,15 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
// Check that the other functions correctly set libc_errno.
- // libc_errno = 0;
+ // LIBC_NAMESPACE::libc_errno = 0;
// ASSERT_NE(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0);
// ASSERT_ERRNO_FAILURE();
- // libc_errno = 0;
+ // LIBC_NAMESPACE::libc_errno = 0;
// ASSERT_NE(LIBC_NAMESPACE::fclose(file), 0);
// ASSERT_ERRNO_FAILURE();
- // libc_errno = 0;
+ // LIBC_NAMESPACE::libc_errno = 0;
// ASSERT_EQ(LIBC_NAMESPACE::fopen("INVALID FILE NAME", "r"),
// static_cast<FILE *>(nullptr));
// ASSERT_ERRNO_FAILURE();
@@ -163,7 +165,7 @@ TEST(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) {
constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct);
constexpr char FILENAME[] = "testdata/fread_fwrite.test";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fwrite(WRITE_DATA, 0, 1, file));
diff --git a/test/src/stdio/fopencookie_test.cpp b/test/src/stdio/fopencookie_test.cpp
index 2edfc7e210d7..6c86b8759801 100644
--- a/test/src/stdio/fopencookie_test.cpp
+++ b/test/src/stdio/fopencookie_test.cpp
@@ -67,7 +67,7 @@ int seek_ss(void *cookie, off64_t *offset, int whence) {
} else if (whence == SEEK_END) {
new_offset = *offset + ss->endpos;
} else {
- libc_errno = EINVAL;
+ LIBC_NAMESPACE::libc_errno = EINVAL;
return -1;
}
if (new_offset < 0 || size_t(new_offset) > ss->bufsize)
@@ -115,7 +115,7 @@ TEST(LlvmLibcFOpenCookie, ReadOnlyCookieTest) {
ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), f));
ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(f);
ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0);
@@ -149,7 +149,7 @@ TEST(LlvmLibcFOpenCookie, WriteOnlyCookieTest) {
LIBC_NAMESPACE::fread(read_data, 1, sizeof(WRITE_DATA), f));
ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0);
ASSERT_ERRNO_EQ(EBADF);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(f);
ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0);
@@ -178,7 +178,7 @@ TEST(LlvmLibcFOpenCookie, AppendOnlyCookieTest) {
ASSERT_EQ(LIBC_NAMESPACE::fread(read_data, 1, READ_SIZE, f), size_t(0));
ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr(f);
ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0);
diff --git a/test/src/stdio/ftell_test.cpp b/test/src/stdio/ftell_test.cpp
index 61b626f53cd2..62745e2194be 100644
--- a/test/src/stdio/ftell_test.cpp
+++ b/test/src/stdio/ftell_test.cpp
@@ -10,7 +10,9 @@
#include "src/stdio/fopen.h"
#include "src/stdio/fread.h"
#include "src/stdio/fseek.h"
+#include "src/stdio/fseeko.h"
#include "src/stdio/ftell.h"
+#include "src/stdio/ftello.h"
#include "src/stdio/fwrite.h"
#include "src/stdio/setvbuf.h"
#include "test/UnitTest/Test.h"
@@ -37,6 +39,13 @@ protected:
// still return the correct effective offset.
ASSERT_EQ(size_t(LIBC_NAMESPACE::ftell(file)), WRITE_SIZE);
+ off_t offseto = 5;
+ ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file, offseto, SEEK_SET));
+ ASSERT_EQ(LIBC_NAMESPACE::ftello(file), offseto);
+ ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file, -offseto, SEEK_END));
+ ASSERT_EQ(size_t(LIBC_NAMESPACE::ftello(file)),
+ size_t(WRITE_SIZE - offseto));
+
long offset = 5;
ASSERT_EQ(0, LIBC_NAMESPACE::fseek(file, offset, SEEK_SET));
ASSERT_EQ(LIBC_NAMESPACE::ftell(file), offset);
diff --git a/test/src/stdio/printf_core/converter_test.cpp b/test/src/stdio/printf_core/converter_test.cpp
index 8404ef6ec7db..9da749f3b8ad 100644
--- a/test/src/stdio/printf_core/converter_test.cpp
+++ b/test/src/stdio/printf_core/converter_test.cpp
@@ -210,6 +210,20 @@ TEST_F(LlvmLibcPrintfConverterTest, HexConversion) {
ASSERT_EQ(writer.get_chars_written(), 18);
}
+TEST_F(LlvmLibcPrintfConverterTest, BinaryConversion) {
+ LIBC_NAMESPACE::printf_core::FormatSection section;
+ section.has_conv = true;
+ section.raw_string = "%b";
+ section.conv_name = 'b';
+ section.conv_val_raw = 42;
+ LIBC_NAMESPACE::printf_core::convert(&writer, section);
+
+ wb.buff[wb.buff_cur] = '\0';
+
+ ASSERT_STREQ(str, "101010");
+ ASSERT_EQ(writer.get_chars_written(), 6);
+}
+
TEST_F(LlvmLibcPrintfConverterTest, PointerConversion) {
LIBC_NAMESPACE::printf_core::FormatSection section;
diff --git a/test/src/stdio/printf_core/parser_test.cpp b/test/src/stdio/printf_core/parser_test.cpp
index 0134277c4a1b..66d6dd0a86c4 100644
--- a/test/src/stdio/printf_core/parser_test.cpp
+++ b/test/src/stdio/printf_core/parser_test.cpp
@@ -223,6 +223,42 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithLongLengthModifier) {
ASSERT_PFORMAT_EQ(expected, format_arr[0]);
}
+TEST(LlvmLibcPrintfParserTest, EvalOneArgWithBitWidthLengthModifier) {
+ LIBC_NAMESPACE::printf_core::FormatSection format_arr[10];
+ const char *str = "%w32d";
+ long long arg1 = 12345;
+ evaluate(format_arr, str, arg1);
+
+ LIBC_NAMESPACE::printf_core::FormatSection expected;
+ expected.has_conv = true;
+
+ expected.raw_string = {str, 5};
+ expected.length_modifier = LIBC_NAMESPACE::printf_core::LengthModifier::w;
+ expected.bit_width = 32;
+ expected.conv_val_raw = arg1;
+ expected.conv_name = 'd';
+
+ ASSERT_PFORMAT_EQ(expected, format_arr[0]);
+}
+
+TEST(LlvmLibcPrintfParserTest, EvalOneArgWithFastBitWidthLengthModifier) {
+ LIBC_NAMESPACE::printf_core::FormatSection format_arr[10];
+ const char *str = "%wf32d";
+ long long arg1 = 12345;
+ evaluate(format_arr, str, arg1);
+
+ LIBC_NAMESPACE::printf_core::FormatSection expected;
+ expected.has_conv = true;
+
+ expected.raw_string = {str, 6};
+ expected.length_modifier = LIBC_NAMESPACE::printf_core::LengthModifier::wf;
+ expected.bit_width = 32;
+ expected.conv_val_raw = arg1;
+ expected.conv_name = 'd';
+
+ ASSERT_PFORMAT_EQ(expected, format_arr[0]);
+}
+
TEST(LlvmLibcPrintfParserTest, EvalOneArgWithAllOptions) {
LIBC_NAMESPACE::printf_core::FormatSection format_arr[10];
const char *str = "% -056.78jd";
diff --git a/test/src/stdio/remove_test.cpp b/test/src/stdio/remove_test.cpp
index 67bff906ef2a..72875600903a 100644
--- a/test/src/stdio/remove_test.cpp
+++ b/test/src/stdio/remove_test.cpp
@@ -20,10 +20,12 @@
TEST(LlvmLibcRemoveTest, CreateAndRemoveFile) {
// The test strategy is to create a file and remove it, and also verify that
// it was removed.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/remove.test.file";
+
+ constexpr const char *FILENAME = "remove.test.file";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
@@ -37,10 +39,11 @@ TEST(LlvmLibcRemoveTest, CreateAndRemoveFile) {
TEST(LlvmLibcRemoveTest, CreateAndRemoveDir) {
// The test strategy is to create a dir and remove it, and also verify that
// it was removed.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata/remove.test.dir";
+ constexpr const char *FILENAME = "remove.test.dir";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
Succeeds(0));
@@ -51,5 +54,5 @@ TEST(LlvmLibcRemoveTest, CreateAndRemoveDir) {
TEST(LlvmLibcRemoveTest, RemoveNonExistent) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- ASSERT_THAT(LIBC_NAMESPACE::remove("testdata/non-existent"), Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::remove("non-existent"), Fails(ENOENT));
}
diff --git a/test/src/stdio/rename_test.cpp b/test/src/stdio/rename_test.cpp
new file mode 100644
index 000000000000..a5dd734c6361
--- /dev/null
+++ b/test/src/stdio/rename_test.cpp
@@ -0,0 +1,51 @@
+//===-- Unittests for rename ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "include/llvm-libc-macros/linux/sys-stat-macros.h"
+#include "include/llvm-libc-macros/linux/unistd-macros.h"
+#include "src/errno/libc_errno.h"
+#include "src/fcntl/open.h"
+#include "src/stdio/rename.h"
+#include "src/unistd/access.h"
+#include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcRenameTest, CreateAndRenameFile) {
+ // The test strategy is to create a file and rename it, and also verify that
+ // it was renamed.
+ LIBC_NAMESPACE::libc_errno = 0;
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+ constexpr const char *FILENAME0 = "rename.test.file0";
+ auto TEST_FILEPATH0 = libc_make_test_file_path(FILENAME0);
+
+ int fd = LIBC_NAMESPACE::open(TEST_FILEPATH0, O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Succeeds(0));
+
+ constexpr const char *FILENAME1 = "rename.test.file1";
+ auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
+ ASSERT_THAT(LIBC_NAMESPACE::rename(TEST_FILEPATH0, TEST_FILEPATH1),
+ Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH1, F_OK), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Fails(ENOENT));
+}
+
+TEST(LlvmLibcRenameTest, RenameNonExistent) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+
+ constexpr const char *FILENAME1 = "rename.test.file1";
+ auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::rename("non-existent", TEST_FILEPATH1),
+ Fails(ENOENT));
+}
diff --git a/test/src/stdio/setvbuf_test.cpp b/test/src/stdio/setvbuf_test.cpp
index 725694bb8ae1..d42ebac12ead 100644
--- a/test/src/stdio/setvbuf_test.cpp
+++ b/test/src/stdio/setvbuf_test.cpp
@@ -102,6 +102,6 @@ TEST(LlvmLibcSetbufTest, InvalidBufferMode) {
0);
ASSERT_ERRNO_EQ(EINVAL);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(f));
}
diff --git a/test/src/stdio/sprintf_test.cpp b/test/src/stdio/sprintf_test.cpp
index 1468bffe2a03..8e9870f71a95 100644
--- a/test/src/stdio/sprintf_test.cpp
+++ b/test/src/stdio/sprintf_test.cpp
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/RoundingModeUtils.h"
#include "test/UnitTest/Test.h"
+#include <inttypes.h>
// TODO: Add a comment here explaining the printf format string.
@@ -33,6 +34,25 @@ using LIBC_NAMESPACE::fputil::testing::RoundingMode;
EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1)); \
EXPECT_STREQ(actual_str, expected_str);
+#define macro_test(FMT, X, expected) \
+ do { \
+ for (char &c : buff) { \
+ c = 0; \
+ } \
+ LIBC_NAMESPACE::sprintf(buff, "%" FMT, X); \
+ ASSERT_STREQ(buff, expected); \
+ } while (0)
+
+TEST(LlvmLibcSPrintfTest, Macros) {
+ char buff[128];
+ macro_test(PRIu8, 1, "1");
+ macro_test(PRIX16, 0xAA, "AA");
+ macro_test(PRId32, -123, "-123");
+ macro_test(PRIX32, 0xFFFFFF85, "FFFFFF85");
+ macro_test(PRIo8, 0xFF, "377");
+ macro_test(PRIo64, 0123, "123");
+}
+
TEST(LlvmLibcSPrintfTest, SimpleNoConv) {
char buff[64];
int written;
@@ -101,8 +121,8 @@ TEST(LlvmLibcSPrintfTest, StringConv) {
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
written = LIBC_NAMESPACE::sprintf(buff, "%s", nullptr);
- EXPECT_EQ(written, 4);
- ASSERT_STREQ(buff, "null");
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "(null)");
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
}
@@ -149,6 +169,93 @@ TEST(LlvmLibcSPrintfTest, IntConv) {
EXPECT_EQ(written, 20);
ASSERT_STREQ(buff, "-9223372036854775808"); // ll min
+ written = LIBC_NAMESPACE::sprintf(buff, "%w3d", 5807);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "7");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w3d", 1);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "1");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w64d", 9223372036854775807ll);
+ EXPECT_EQ(written, 19);
+ ASSERT_STREQ(buff, "9223372036854775807");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w-1d", 5807);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "%w-1d");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w0d", 5807);
+ EXPECT_EQ(written, 4);
+ ASSERT_STREQ(buff, "%w0d");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w999d", 9223372036854775807ll);
+ EXPECT_EQ(written, 19);
+ ASSERT_STREQ(buff, "9223372036854775807");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%winvalid%w1d", 5807, 5807);
+ EXPECT_EQ(written, 10);
+ ASSERT_STREQ(buff, "%winvalid1");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w-1d%w1d", 5807, 5807);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "%w-1d1");
+
+ char format[64];
+ char uintmax[128];
+ LIBC_NAMESPACE::sprintf(format, "%%w%du", sizeof(uintmax_t) * CHAR_BIT);
+ const int uintmax_len =
+ LIBC_NAMESPACE::sprintf(uintmax, "%ju", sizeof(uintmax_t) * CHAR_BIT);
+ written = LIBC_NAMESPACE::sprintf(buff, format, sizeof(uintmax_t) * CHAR_BIT);
+ EXPECT_EQ(written, uintmax_len);
+ ASSERT_STREQ(buff, uintmax);
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%w64u", 18446744073709551615ull);
+ EXPECT_EQ(written, 20);
+ ASSERT_STREQ(buff, "18446744073709551615"); // ull max
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%w64d", -9223372036854775807ll - 1ll);
+ EXPECT_EQ(written, 20);
+ ASSERT_STREQ(buff, "-9223372036854775808"); // ll min
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf3d", 5807);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "7");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf3d", 1);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "1");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf64u", 18446744073709551615ull);
+ EXPECT_EQ(written, 20);
+ ASSERT_STREQ(buff, "18446744073709551615"); // ull max
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%wf64d", -9223372036854775807ll - 1ll);
+ EXPECT_EQ(written, 20);
+ ASSERT_STREQ(buff, "-9223372036854775808"); // ll min
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf0d", 5807);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "%wf0d");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf-1d", 5807);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "%wf-1d");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wfinvalid%wf1d", 5807, 5807);
+ EXPECT_EQ(written, 11);
+ ASSERT_STREQ(buff, "%wfinvalid1");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf-1d%wf1d", 5807, 5807);
+ EXPECT_EQ(written, 7);
+ ASSERT_STREQ(buff, "%wf-1d1");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%wf999d", 9223372036854775807ll);
+ EXPECT_EQ(written, 19);
+ ASSERT_STREQ(buff, "9223372036854775807");
+
// Min Width Tests.
written = LIBC_NAMESPACE::sprintf(buff, "%4d", 789);
@@ -390,6 +497,119 @@ TEST(LlvmLibcSPrintfTest, HexConv) {
ASSERT_STREQ(buff, "007F 0x1000000000 002 ");
}
+TEST(LlvmLibcSPrintfTest, BinConv) {
+ char buff[64];
+ int written;
+
+ // Basic Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%b", 42);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "101010");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%B", 12081991);
+ EXPECT_EQ(written, 24);
+ ASSERT_STREQ(buff, "101110000101101101000111");
+
+ // Min Width Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%10b", 0b101010);
+ EXPECT_EQ(written, 10);
+ ASSERT_STREQ(buff, " 101010");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%2B", 0b101010);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "101010");
+
+ // Precision Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%b", 0);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "0");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%.0b", 0);
+ EXPECT_EQ(written, 0);
+ ASSERT_STREQ(buff, "");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%.5b", 0b111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "00111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%.2b", 0b111);
+ EXPECT_EQ(written, 3);
+ ASSERT_STREQ(buff, "111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%3b", 0b111);
+ EXPECT_EQ(written, 3);
+ ASSERT_STREQ(buff, "111");
+
+ // Flag Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-5b", 0b111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "111 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#b", 0b111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "0b111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#b", 0);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "0");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#B", 0b111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "0B111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%05b", 0b111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, "00111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%0#6b", 0b111);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "0b0111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-#6b", 0b111);
+ EXPECT_EQ(written, 6);
+ ASSERT_STREQ(buff, "0b111 ");
+
+ // Combined Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#-07b", 0b111);
+ EXPECT_EQ(written, 7);
+ ASSERT_STREQ(buff, "0b111 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%7.5b", 0b111);
+ EXPECT_EQ(written, 7);
+ ASSERT_STREQ(buff, " 00111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#9.5B", 0b111);
+ EXPECT_EQ(written, 9);
+ ASSERT_STREQ(buff, " 0B00111");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#.b", 0);
+ EXPECT_EQ(written, 0);
+ ASSERT_STREQ(buff, "");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-7.5b", 0b111);
+ EXPECT_EQ(written, 7);
+ ASSERT_STREQ(buff, "00111 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%5.4b", 0b1111);
+ EXPECT_EQ(written, 5);
+ ASSERT_STREQ(buff, " 1111");
+
+ // Multiple Conversion Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%10B %-#10b", 0b101, 0b110);
+ EXPECT_EQ(written, 21);
+ ASSERT_STREQ(buff, " 101 0b110 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-5.4b%#.4b", 0b101, 0b110);
+ EXPECT_EQ(written, 11);
+ ASSERT_STREQ(buff, "0101 0b0110");
+}
+
TEST(LlvmLibcSPrintfTest, PointerConv) {
char buff[64];
int written;
@@ -642,29 +862,29 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
// Length Modifier Tests.
written = LIBC_NAMESPACE::sprintf(buff, "%La", 0.1L);
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.ccccccccccccccdp-7");
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
-#else // 128 bit long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.999999999999999999999999999ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%La", 1.0e1000L);
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xf.38db1f9dd3dac05p+3318");
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
-#else // 128 bit long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.e71b63f3ba7b580af1a52d2a7379p+3321");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%La", 1.0e-1000L);
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0x8.68a9188a89e1467p-3325");
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x0p+0");
-#else // 128 bit long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.0d152311513c28ce202627c06ec2p-3322");
#endif
@@ -766,20 +986,20 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
ASSERT_STREQ_LEN(written, buff, "0x0p+0");
written = LIBC_NAMESPACE::sprintf(buff, "%.1La", 0.1L);
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
-#else // 128 bit long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%.1La", 0xf.fffffffffffffffp16380L);
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
-#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
-#else // 128 bit long double
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
#endif
@@ -1025,8 +1245,8 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
// Some float128 systems (specifically the ones used for aarch64 buildbots)
// don't respect signs for long double NaNs.
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80) || \
- defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) || \
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
written = LIBC_NAMESPACE::sprintf(buff, "%LF", -ld_nan);
ASSERT_STREQ_LEN(written, buff, "-NAN");
#endif
@@ -1221,20 +1441,20 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
/*
written = LIBC_NAMESPACE::sprintf(buff, "%.1La", 0.1L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%.1La",
- 0xf.fffffffffffffffp16380L); #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
- ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ 0xf.fffffffffffffffp16380L); #if
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) ASSERT_STREQ_LEN(written, buff,
+ "0x1.0p+16384"); #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
#endif
*/
@@ -1470,8 +1690,8 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalLongDoubleConv) {
// Length Modifier Tests.
- // TODO(michaelrj): Add tests for LIBC_LONG_DOUBLE_IS_FLOAT64 and 128 bit long
- // double systems.
+ // TODO(michaelrj): Add tests for LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64 and 128
+ // bit long double systems.
// TODO(michaelrj): Fix the tests to only depend on the digits the long double
// is accurate for.
@@ -1481,7 +1701,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalLongDoubleConv) {
written = LIBC_NAMESPACE::sprintf(buff, "%.Lf", -2.5L);
ASSERT_STREQ_LEN(written, buff, "-2");
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
written = LIBC_NAMESPACE::sprintf(buff, "%Lf", 1e100L);
ASSERT_STREQ_LEN(written, buff,
@@ -1797,7 +2017,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalLongDoubleConv) {
"570449525088342437216896462077260223998756027453411520977536701491759878"
"422771447006016890777855573925295187921971811871399320142563330377888532"
"179817332113");
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
}
TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
@@ -2038,20 +2258,20 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
/*
written = LIBC_NAMESPACE::sprintf(buff, "%.1La", 0.1L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%.1La",
- 0xf.fffffffffffffffp16380L); #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
- ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ 0xf.fffffffffffffffp16380L); #if
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) ASSERT_STREQ_LEN(written, buff,
+ "0x1.0p+16384"); #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
#endif
*/
@@ -2290,7 +2510,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentLongDoubleConv) {
ForceRoundingMode r(RoundingMode::Nearest);
// Length Modifier Tests.
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
written = LIBC_NAMESPACE::sprintf(buff, "%.9Le", 1000000000500000000.1L);
ASSERT_STREQ_LEN(written, buff, "1.000000001e+18");
@@ -2650,34 +2870,34 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
written = LIBC_NAMESPACE::sprintf(buff, "%.10g", 0x1.0p-1074);
ASSERT_STREQ_LEN(written, buff, "4.940656458e-324");
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
written = LIBC_NAMESPACE::sprintf(buff, "%.60Lg", 0xa.aaaaaaaaaaaaaabp-7L);
ASSERT_STREQ_LEN(
written, buff,
"0.0833333333333333333355920878593448009041821933351457118988037");
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
// Long double precision tests.
// These are currently commented out because they require long double support
// that isn't ready yet.
/*
written = LIBC_NAMESPACE::sprintf(buff, "%.1La", 0.1L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%.1La",
- 0xf.fffffffffffffffp16380L); #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
- ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ 0xf.fffffffffffffffp16380L); #if
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80) ASSERT_STREQ_LEN(written, buff,
+ "0x1.0p+16384"); #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
#endif
*/
@@ -2920,7 +3140,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoLongDoubleConv) {
// Length Modifier Tests.
-#if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
written = LIBC_NAMESPACE::sprintf(buff, "%Lg", 0xf.fffffffffffffffp+16380L);
ASSERT_STREQ_LEN(written, buff, "1.18973e+4932");
@@ -2931,7 +3151,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoLongDoubleConv) {
written = LIBC_NAMESPACE::sprintf(buff, "%Lg", 9.99999999999e-100L);
ASSERT_STREQ_LEN(written, buff, "1e-99");
-#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
// TODO: Uncomment the below tests after long double support is added
/*
@@ -3038,29 +3258,29 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoLongDoubleConv) {
*/
/*
written = LIBC_NAMESPACE::sprintf(buff, "%La", 0.1L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xc.ccccccccccccccdp-7");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.999999999999999999999999999ap-4");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%La", 1.0e1000L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0xf.38db1f9dd3dac05p+3318");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "inf");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.e71b63f3ba7b580af1a52d2a7379p+3321");
#endif
written = LIBC_NAMESPACE::sprintf(buff, "%La", 1.0e-1000L);
- #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+ #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
ASSERT_STREQ_LEN(written, buff, "0x8.68a9188a89e1467p-3325");
- #elif defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
ASSERT_STREQ_LEN(written, buff, "0x0p+0");
- #else // 128 bit long double
+ #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
ASSERT_STREQ_LEN(written, buff, "0x1.0d152311513c28ce202627c06ec2p-3322");
#endif
*/
@@ -3068,6 +3288,217 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoLongDoubleConv) {
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
+#if defined(LIBC_COMPILER_HAS_FIXED_POINT) && \
+ !defined(LIBC_COPT_PRINTF_DISABLE_FIXED_POINT)
+TEST_F(LlvmLibcSPrintfTest, FixedConv) {
+
+ // These numeric tests are potentially a little weak, but the fuzz test is
+ // more thorough than my handwritten tests tend to be.
+
+ // TODO: Replace hex literals with their appropriate fixed point literals.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%k", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%k", 0x80000000); // -0.0
+ ASSERT_STREQ_LEN(written, buff, "-0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%r", 0xffff); // -fract max
+ ASSERT_STREQ_LEN(written, buff, "-0.999969");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%R", 0xffff); // unsigned fract max
+ ASSERT_STREQ_LEN(written, buff, "0.999985");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%k", 0xffffffff); // -accum max
+ ASSERT_STREQ_LEN(written, buff, "-65535.999969");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%K", 0xffffffff); // unsigned accum max
+ ASSERT_STREQ_LEN(written, buff, "65535.999985");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%r", 0x7fff); // fract max
+ ASSERT_STREQ_LEN(written, buff, "0.999969");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%k", 0x7fffffff); // accum max
+ ASSERT_STREQ_LEN(written, buff, "65535.999969");
+
+ // Length Modifier Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hk", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hk", 0xffff); // -short accum max
+ ASSERT_STREQ_LEN(written, buff, "-255.992188");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hr", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hr", 0xff); // -short fract max
+ ASSERT_STREQ_LEN(written, buff, "-0.992188");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hK", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%hK", 0xffff); // unsigned short accum max
+ ASSERT_STREQ_LEN(written, buff, "255.996094");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%hR", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%hR", 0xff); // unsigned short fract max
+ ASSERT_STREQ_LEN(written, buff, "0.996094");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lk", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lk",
+ 0xffffffffffffffff); //-long accum max
+ ASSERT_STREQ_LEN(written, buff, "-4294967296.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lr", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lr",
+ 0xffffffff); //-long fract max
+ ASSERT_STREQ_LEN(written, buff, "-1.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lK", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%lK",
+ 0xffffffffffffffff); // unsigned long accum max
+ ASSERT_STREQ_LEN(written, buff, "4294967296.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lR", 0x0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%lR",
+ 0xffffffff); // unsigned long fract max
+ ASSERT_STREQ_LEN(written, buff, "1.000000");
+
+ // Min Width Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%10k", 0x0000a000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, " 1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%10k", 0x8000a000); //-1.25
+ ASSERT_STREQ_LEN(written, buff, " -1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%8k", 0x0000a000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, "1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%9k", 0x8000a000); //-1.25
+ ASSERT_STREQ_LEN(written, buff, "-1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%4k", 0x0000a000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, "1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%4k", 0x8000a000); //-1.25
+ ASSERT_STREQ_LEN(written, buff, "-1.250000");
+
+ // Precision Tests.
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%.16K", 0xFFFFFFFF); // unsigned accum max
+ ASSERT_STREQ_LEN(written, buff, "65535.9999847412109375");
+
+ written = LIBC_NAMESPACE::sprintf(
+ buff, "%.32lK", 0xFFFFFFFFFFFFFFFF); // unsigned long accum max
+ ASSERT_STREQ_LEN(written, buff,
+ "4294967295.99999999976716935634613037109375");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%.0K", 0xFFFFFFFF); // unsigned accum max
+ ASSERT_STREQ_LEN(written, buff, "65536");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%.0R", 0xFFFF); // unsigned fract max
+ ASSERT_STREQ_LEN(written, buff, "1");
+
+ // Flag Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%+k", 0x0000a000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, "+1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%+k", 0x8000a000); //-1.25
+ ASSERT_STREQ_LEN(written, buff, "-1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "% k", 0x0000a000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, " 1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "% k", 0x8000a000); //-1.25
+ ASSERT_STREQ_LEN(written, buff, "-1.250000");
+
+ // unsigned variants ignore sign flags.
+ written = LIBC_NAMESPACE::sprintf(buff, "%+K", 0x00014000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, "1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "% K", 0x00014000); // 1.25
+ ASSERT_STREQ_LEN(written, buff, "1.250000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-10k", 0x0000c000); // 1.5
+ ASSERT_STREQ_LEN(written, buff, "1.500000 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#.k", 0x00008000); // 1.0
+ ASSERT_STREQ_LEN(written, buff, "1.");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%#.0k", 0x0000c000); // 1.5
+ ASSERT_STREQ_LEN(written, buff, "2.");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%010k", 0x0000c000); // 1.5
+ ASSERT_STREQ_LEN(written, buff, "001.500000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%010k", 0x8000c000); //-1.5
+ ASSERT_STREQ_LEN(written, buff, "-01.500000");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%+- #0k", 0); // 0.0
+ ASSERT_STREQ_LEN(written, buff, "+0.000000");
+
+ // Combined Tests.
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%10.2k", 0x0004feb8); // 9.99
+ ASSERT_STREQ_LEN(written, buff, " 9.99");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%5.1k", 0x0004feb8); // 9.99
+ ASSERT_STREQ_LEN(written, buff, " 10.0");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-10.2k", 0x0004feb8); // 9.99
+ ASSERT_STREQ_LEN(written, buff, "9.99 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-5.1k", 0x0004feb8); // 9.99
+ ASSERT_STREQ_LEN(written, buff, "10.0 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-5.1k", 0x00000001); // accum min
+ ASSERT_STREQ_LEN(written, buff, "0.0 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%30k", 0x7fffffff); // accum max
+ ASSERT_STREQ_LEN(written, buff, " 65535.999969");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%-30k", 0x7fffffff); // accum max
+ ASSERT_STREQ_LEN(written, buff, "65535.999969 ");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%20.2lK",
+ 0x3b9ac9ffFD70A3D7); // 999999999.99
+ ASSERT_STREQ_LEN(written, buff, " 999999999.99");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%20.1lK",
+ 0x3b9ac9ffFD70A3D7); // 999999999.99
+ ASSERT_STREQ_LEN(written, buff, " 1000000000.0");
+
+ written = LIBC_NAMESPACE::sprintf(buff, "%12.3R %-12.3k", 0x1999,
+ 0x00800000); // 0.1, 256.0
+ ASSERT_STREQ_LEN(written, buff, " 0.100 256.000 ");
+
+ written =
+ LIBC_NAMESPACE::sprintf(buff, "%+-#12.3lk % 012.3k", 0x000000001013a92a,
+ 0x02740000); // 0.126, 1256.0
+ ASSERT_STREQ_LEN(written, buff, "+0.126 0001256.000");
+}
+#endif // defined(LIBC_COMPILER_HAS_FIXED_POINT) &&
+ // !defined(LIBC_COPT_PRINTF_DISABLE_FIXED_POINT)
+
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
TEST(LlvmLibcSPrintfTest, WriteIntConv) {
char buff[64];
diff --git a/test/src/stdio/sscanf_test.cpp b/test/src/stdio/sscanf_test.cpp
index 743704b49d1d..741815bb1517 100644
--- a/test/src/stdio/sscanf_test.cpp
+++ b/test/src/stdio/sscanf_test.cpp
@@ -322,7 +322,7 @@ TEST(LlvmLibcSScanfTest, FloatConvLengthModifier) {
EXPECT_EQ(ret_val, 1);
// 1e600 may be larger than the maximum long double (if long double is double).
// In that case both of these should be evaluated as inf.
-#ifdef LIBC_LONG_DOUBLE_IS_FLOAT64
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
EXPECT_FP_EQ(ld_result, d_inf);
#else
EXPECT_FP_EQ(ld_result, 1.0e600L);
diff --git a/test/src/stdio/unlocked_fileop_test.cpp b/test/src/stdio/unlocked_fileop_test.cpp
index cf20701ca0e3..09697a6452f4 100644
--- a/test/src/stdio/unlocked_fileop_test.cpp
+++ b/test/src/stdio/unlocked_fileop_test.cpp
@@ -37,7 +37,7 @@ TEST(LlvmLibcFILETest, UnlockedReadAndWrite) {
LIBC_NAMESPACE::fread_unlocked(data, 1, sizeof(READ_SIZE), f));
ASSERT_NE(LIBC_NAMESPACE::ferror_unlocked(f), 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr_unlocked(f);
ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(f), 0);
@@ -58,7 +58,7 @@ TEST(LlvmLibcFILETest, UnlockedReadAndWrite) {
LIBC_NAMESPACE::fwrite_unlocked(CONTENT, 1, sizeof(CONTENT), f));
ASSERT_NE(LIBC_NAMESPACE::ferror_unlocked(f), 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::clearerr_unlocked(f);
ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(f), 0);
diff --git a/test/src/stdlib/StrfromTest.h b/test/src/stdlib/StrfromTest.h
new file mode 100644
index 000000000000..0db507ef0716
--- /dev/null
+++ b/test/src/stdlib/StrfromTest.h
@@ -0,0 +1,500 @@
+//===-- A template class for testing strfrom functions ----------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/Test.h"
+
+#define ASSERT_STREQ_LEN(actual_written, actual_str, expected_str) \
+ EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1)); \
+ EXPECT_STREQ(actual_str, expected_str);
+
+template <typename InputT>
+class StrfromTest : public LIBC_NAMESPACE::testing::Test {
+
+ static const bool is_single_prec =
+ LIBC_NAMESPACE::cpp::is_same<InputT, float>::value;
+ static const bool is_double_prec =
+ LIBC_NAMESPACE::cpp::is_same<InputT, double>::value;
+
+ using FunctionT = int (*)(char *, size_t, const char *, InputT fp);
+
+public:
+ void floatDecimalFormat(FunctionT func) {
+ if (is_single_prec)
+ floatDecimalSinglePrec(func);
+ else if (is_double_prec)
+ floatDecimalDoublePrec(func);
+ else
+ floatDecimalLongDoublePrec(func);
+ }
+
+ void floatHexExpFormat(FunctionT func) {
+ if (is_single_prec)
+ floatHexExpSinglePrec(func);
+ else if (is_double_prec)
+ floatHexExpDoublePrec(func);
+ else
+ floatHexExpLongDoublePrec(func);
+ }
+
+ void floatDecimalExpFormat(FunctionT func) {
+ if (is_single_prec)
+ floatDecimalExpSinglePrec(func);
+ else if (is_double_prec)
+ floatDecimalExpDoublePrec(func);
+ else
+ floatDecimalExpLongDoublePrec(func);
+ }
+
+ void floatDecimalAutoFormat(FunctionT func) {
+ if (is_single_prec)
+ floatDecimalAutoSinglePrec(func);
+ else if (is_double_prec)
+ floatDecimalAutoDoublePrec(func);
+ else
+ floatDecimalAutoLongDoublePrec(func);
+ }
+
+ void improperFormatString(FunctionT func) {
+ char buff[100];
+ int written;
+ const bool is_long_double = !is_single_prec && !is_double_prec;
+
+ written = func(buff, 37, "A simple string with no conversions.", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "A simple string with no conversions.");
+
+ written =
+ func(buff, 37,
+ "%A simple string with one conversion, should overwrite.", 1.0);
+ if (is_long_double) {
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0X8P-3");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+#endif
+ } else {
+ // not long double
+ ASSERT_STREQ_LEN(written, buff, "0X1P+0");
+ }
+ written = func(buff, 74,
+ "A simple string with one conversion in %A "
+ "between, writes string as it is",
+ 1.0);
+ ASSERT_STREQ_LEN(written, buff,
+ "A simple string with one conversion in %A between, "
+ "writes string as it is");
+
+ written = func(buff, 36, "A simple string with one conversion", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "A simple string with one conversion");
+
+ written = func(buff, 20, "%1f", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "%1f");
+ }
+
+ void insufficentBufsize(FunctionT func) {
+ char buff[20];
+ int written;
+
+ written = func(buff, 5, "%f", 1234567890.0);
+ EXPECT_EQ(written, 17);
+ ASSERT_STREQ(buff, "1234");
+
+ written = func(buff, 5, "%.5f", 1.05);
+ EXPECT_EQ(written, 7);
+ ASSERT_STREQ(buff, "1.05");
+
+ written = func(buff, 0, "%g", 1.0);
+ EXPECT_EQ(written, 1);
+ ASSERT_STREQ(buff, "1.05"); // Make sure that buff has not changed
+ }
+
+ void infNanValues(FunctionT func) {
+ if (is_double_prec)
+ doublePrecInfNan(func);
+ else if (!is_single_prec)
+ longDoublePrecInfNan(func);
+ }
+
+ void floatDecimalSinglePrec(FunctionT func) {
+ char buff[70];
+ int written;
+
+ written = func(buff, 16, "%f", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "1.000000");
+
+ written = func(buff, 20, "%f", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "1234567936.000000");
+
+ written = func(buff, 67, "%.3f", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "1.000");
+ }
+
+ void floatDecimalDoublePrec(FunctionT func) {
+ char buff[500];
+ int written;
+
+ written = func(buff, 99, "%f", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "1.000000");
+
+ written = func(buff, 99, "%F", -1.0);
+ ASSERT_STREQ_LEN(written, buff, "-1.000000");
+
+ written = func(buff, 99, "%f", -1.234567);
+ ASSERT_STREQ_LEN(written, buff, "-1.234567");
+
+ written = func(buff, 99, "%f", 0.0);
+ ASSERT_STREQ_LEN(written, buff, "0.000000");
+
+ written = func(buff, 99, "%f", 1.5);
+ ASSERT_STREQ_LEN(written, buff, "1.500000");
+
+ written = func(buff, 499, "%f", 1e300);
+ ASSERT_STREQ_LEN(written, buff,
+ "100000000000000005250476025520442024870446858110815915491"
+ "585411551180245"
+ "798890819578637137508044786404370444383288387817694252323"
+ "536043057564479"
+ "218478670698284838720092657580373783023379478809005936895"
+ "323497079994508"
+ "111903896764088007465274278014249457925878882005684283811"
+ "566947219638686"
+ "5459400540160.000000");
+
+ written = func(buff, 99, "%f", 0.1);
+ ASSERT_STREQ_LEN(written, buff, "0.100000");
+
+ written = func(buff, 99, "%f", 1234567890123456789.0);
+ ASSERT_STREQ_LEN(written, buff, "1234567890123456768.000000");
+
+ written = func(buff, 99, "%f", 9999999999999.99);
+ ASSERT_STREQ_LEN(written, buff, "9999999999999.990234");
+
+ written = func(buff, 99, "%f", 0.1);
+ ASSERT_STREQ_LEN(written, buff, "0.100000");
+
+ written = func(buff, 99, "%f", 1234567890123456789.0);
+ ASSERT_STREQ_LEN(written, buff, "1234567890123456768.000000");
+
+ written = func(buff, 99, "%f", 9999999999999.99);
+ ASSERT_STREQ_LEN(written, buff, "9999999999999.990234");
+
+ // Precision Tests
+ written = func(buff, 100, "%.2f", 9999999999999.99);
+ ASSERT_STREQ_LEN(written, buff, "9999999999999.99");
+
+ written = func(buff, 100, "%.1f", 9999999999999.99);
+ ASSERT_STREQ_LEN(written, buff, "10000000000000.0");
+
+ written = func(buff, 100, "%.5f", 1.25);
+ ASSERT_STREQ_LEN(written, buff, "1.25000");
+
+ written = func(buff, 100, "%.0f", 1.25);
+ ASSERT_STREQ_LEN(written, buff, "1");
+
+ written = func(buff, 100, "%.20f", 1.234e-10);
+ ASSERT_STREQ_LEN(written, buff, "0.00000000012340000000");
+ }
+
+ void floatDecimalLongDoublePrec(FunctionT func) {
+ char buff[45];
+ int written;
+
+ written = func(buff, 40, "%f", 1.0L);
+ ASSERT_STREQ_LEN(written, buff, "1.000000");
+
+ written = func(buff, 10, "%.f", -2.5L);
+ ASSERT_STREQ_LEN(written, buff, "-2");
+ }
+
+ void floatHexExpSinglePrec(FunctionT func) {
+ char buff[25];
+ int written;
+
+ written = func(buff, 0, "%a", 1234567890.0);
+ EXPECT_EQ(written, 14);
+
+ written = func(buff, 20, "%a", 1234567890.0);
+ EXPECT_EQ(written, 14);
+ ASSERT_STREQ(buff, "0x1.26580cp+30");
+
+ written = func(buff, 20, "%A", 1234567890.0);
+ EXPECT_EQ(written, 14);
+ ASSERT_STREQ(buff, "0X1.26580CP+30");
+ }
+
+ void floatHexExpDoublePrec(FunctionT func) {
+ char buff[60];
+ int written;
+
+ written = func(buff, 10, "%a", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "0x1p+0");
+
+ written = func(buff, 10, "%A", -1.0);
+ ASSERT_STREQ_LEN(written, buff, "-0X1P+0");
+
+ written = func(buff, 30, "%a", -0x1.abcdef12345p0);
+ ASSERT_STREQ_LEN(written, buff, "-0x1.abcdef12345p+0");
+
+ written = func(buff, 50, "%A", 0x1.abcdef12345p0);
+ ASSERT_STREQ_LEN(written, buff, "0X1.ABCDEF12345P+0");
+
+ written = func(buff, 10, "%a", 0.0);
+ ASSERT_STREQ_LEN(written, buff, "0x0p+0");
+
+ written = func(buff, 40, "%a", 1.0e100);
+ ASSERT_STREQ_LEN(written, buff, "0x1.249ad2594c37dp+332");
+
+ written = func(buff, 30, "%a", 0.1);
+ ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
+ }
+
+ void floatHexExpLongDoublePrec(FunctionT func) {
+ char buff[55];
+ int written;
+
+ written = func(buff, 50, "%a", 0.1L);
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0xc.ccccccccccccccdp-7");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0x1.999999999999999999999999999ap-4");
+#endif
+
+ written = func(buff, 20, "%.1a", 0.1L);
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
+#endif
+
+ written = func(buff, 50, "%a", 1.0e1000L);
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0xf.38db1f9dd3dac05p+3318");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "inf");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0x1.e71b63f3ba7b580af1a52d2a7379p+3321");
+#endif
+
+ written = func(buff, 50, "%a", 1.0e-1000L);
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0x8.68a9188a89e1467p-3325");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "0x0p+0");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0x1.0d152311513c28ce202627c06ec2p-3322");
+#endif
+
+ written = func(buff, 50, "%.1a", 0xf.fffffffffffffffp16380L);
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ ASSERT_STREQ_LEN(written, buff, "inf");
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
+#endif
+ }
+
+ void floatDecimalExpSinglePrec(FunctionT func) {
+ char buff[25];
+ int written;
+
+ written = func(buff, 20, "%.9e", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "1.234567936e+09");
+
+ written = func(buff, 20, "%.9E", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "1.234567936E+09");
+ }
+
+ void floatDecimalExpDoublePrec(FunctionT func) {
+ char buff[101];
+ int written;
+
+ written = func(buff, 100, "%e", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "1.000000e+00");
+
+ written = func(buff, 100, "%E", -1.0);
+ ASSERT_STREQ_LEN(written, buff, "-1.000000E+00");
+
+ written = func(buff, 100, "%e", -1.234567);
+ ASSERT_STREQ_LEN(written, buff, "-1.234567e+00");
+
+ written = func(buff, 100, "%e", 0.0);
+ ASSERT_STREQ_LEN(written, buff, "0.000000e+00");
+
+ written = func(buff, 100, "%e", 1.5);
+ ASSERT_STREQ_LEN(written, buff, "1.500000e+00");
+
+ written = func(buff, 100, "%e", 1e300);
+ ASSERT_STREQ_LEN(written, buff, "1.000000e+300");
+
+ written = func(buff, 100, "%e", 1234567890123456789.0);
+ ASSERT_STREQ_LEN(written, buff, "1.234568e+18");
+
+ // Precision Tests
+ written = func(buff, 100, "%.1e", 1.0);
+ ASSERT_STREQ_LEN(written, buff, "1.0e+00");
+
+ written = func(buff, 100, "%.1e", 1.99);
+ ASSERT_STREQ_LEN(written, buff, "2.0e+00");
+
+ written = func(buff, 100, "%.1e", 9.99);
+ ASSERT_STREQ_LEN(written, buff, "1.0e+01");
+ }
+
+ void floatDecimalExpLongDoublePrec(FunctionT func) {
+ // Mark as maybe_unused to silence unused variable
+ // warning when long double is not 80-bit
+ [[maybe_unused]] char buff[100];
+ [[maybe_unused]] int written;
+
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ written = func(buff, 90, "%.9e", 1000000000500000000.1L);
+ ASSERT_STREQ_LEN(written, buff, "1.000000001e+18");
+
+ written = func(buff, 90, "%.9e", 1000000000500000000.0L);
+ ASSERT_STREQ_LEN(written, buff, "1.000000000e+18");
+
+ written = func(buff, 90, "%e", 0xf.fffffffffffffffp+16380L);
+ ASSERT_STREQ_LEN(written, buff, "1.189731e+4932");
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+ }
+
+ void floatDecimalAutoSinglePrec(FunctionT func) {
+ char buff[25];
+ int written;
+
+ written = func(buff, 20, "%.9g", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "1.23456794e+09");
+
+ written = func(buff, 20, "%.9G", 1234567890.0);
+ ASSERT_STREQ_LEN(written, buff, "1.23456794E+09");
+ }
+
+ void floatDecimalAutoDoublePrec(FunctionT func) {
+ char buff[120];
+ int written;
+
+ written = func(buff, 100, "%g", 1234567890123456789.0);
+ ASSERT_STREQ_LEN(written, buff, "1.23457e+18");
+
+ written = func(buff, 100, "%g", 9999990000000.00);
+ ASSERT_STREQ_LEN(written, buff, "9.99999e+12");
+
+ written = func(buff, 100, "%g", 9999999000000.00);
+ ASSERT_STREQ_LEN(written, buff, "1e+13");
+
+ written = func(buff, 100, "%g", 0xa.aaaaaaaaaaaaaabp-7);
+ ASSERT_STREQ_LEN(written, buff, "0.0833333");
+
+ written = func(buff, 100, "%g", 0.00001);
+ ASSERT_STREQ_LEN(written, buff, "1e-05");
+
+ // Precision Tests
+ written = func(buff, 100, "%.0g", 0.0);
+ ASSERT_STREQ_LEN(written, buff, "0");
+
+ written = func(buff, 100, "%.2g", 0.1);
+ ASSERT_STREQ_LEN(written, buff, "0.1");
+
+ written = func(buff, 100, "%.2g", 1.09);
+ ASSERT_STREQ_LEN(written, buff, "1.1");
+
+ written = func(buff, 100, "%.15g", 22.25);
+ ASSERT_STREQ_LEN(written, buff, "22.25");
+
+ written = func(buff, 100, "%.20g", 1.234e-10);
+ ASSERT_STREQ_LEN(written, buff, "1.2340000000000000814e-10");
+ }
+
+ void floatDecimalAutoLongDoublePrec(FunctionT func) {
+ // Mark as maybe_unused to silence unused variable
+ // warning when long double is not 80-bit
+ [[maybe_unused]] char buff[100];
+ [[maybe_unused]] int written;
+
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ written = func(buff, 99, "%g", 0xf.fffffffffffffffp+16380L);
+ ASSERT_STREQ_LEN(written, buff, "1.18973e+4932");
+
+ written = func(buff, 99, "%g", 0xa.aaaaaaaaaaaaaabp-7L);
+ ASSERT_STREQ_LEN(written, buff, "0.0833333");
+
+ written = func(buff, 99, "%g", 9.99999999999e-100L);
+ ASSERT_STREQ_LEN(written, buff, "1e-99");
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+ }
+
+ void doublePrecInfNan(FunctionT func) {
+ char buff[15];
+ int written;
+
+ double inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
+ double nan = LIBC_NAMESPACE::fputil::FPBits<double>::quiet_nan().get_val();
+
+ written = func(buff, 10, "%f", inf);
+ ASSERT_STREQ_LEN(written, buff, "inf");
+
+ written = func(buff, 10, "%A", -inf);
+ ASSERT_STREQ_LEN(written, buff, "-INF");
+
+ written = func(buff, 10, "%f", nan);
+ ASSERT_STREQ_LEN(written, buff, "nan");
+
+ written = func(buff, 10, "%A", -nan);
+ ASSERT_STREQ_LEN(written, buff, "-NAN");
+ }
+
+ void longDoublePrecInfNan(FunctionT func) {
+ char buff[15];
+ int written;
+
+ long double ld_inf =
+ LIBC_NAMESPACE::fputil::FPBits<long double>::inf().get_val();
+ long double ld_nan =
+ LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
+
+ written = func(buff, 10, "%f", ld_inf);
+ ASSERT_STREQ_LEN(written, buff, "inf");
+
+ written = func(buff, 10, "%A", -ld_inf);
+ ASSERT_STREQ_LEN(written, buff, "-INF");
+
+ written = func(buff, 10, "%f", ld_nan);
+ ASSERT_STREQ_LEN(written, buff, "nan");
+
+ written = func(buff, 10, "%A", -ld_nan);
+ ASSERT_STREQ_LEN(written, buff, "-NAN");
+ }
+};
+
+#define STRFROM_TEST(InputType, name, func) \
+ using LlvmLibc##name##Test = StrfromTest<InputType>; \
+ TEST_F(LlvmLibc##name##Test, FloatDecimalFormat) { \
+ floatDecimalFormat(func); \
+ } \
+ TEST_F(LlvmLibc##name##Test, FloatHexExpFormat) { floatHexExpFormat(func); } \
+ TEST_F(LlvmLibc##name##Test, FloatDecimalAutoFormat) { \
+ floatDecimalAutoFormat(func); \
+ } \
+ TEST_F(LlvmLibc##name##Test, FloatDecimalExpFormat) { \
+ floatDecimalExpFormat(func); \
+ } \
+ TEST_F(LlvmLibc##name##Test, ImproperFormatString) { \
+ improperFormatString(func); \
+ } \
+ TEST_F(LlvmLibc##name##Test, InsufficientBufferSize) { \
+ insufficentBufsize(func); \
+ } \
+ TEST_F(LlvmLibc##name##Test, InfAndNanValues) { infNanValues(func); }
diff --git a/test/src/stdlib/StrtolTest.h b/test/src/stdlib/StrtolTest.h
index 8f1723b03861..8a67848e4c33 100644
--- a/test/src/stdlib/StrtolTest.h
+++ b/test/src/stdlib/StrtolTest.h
@@ -35,7 +35,7 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
void InvalidBase(FunctionT func) {
const char *ten = "10";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(ten, nullptr, -1), ReturnT(0));
ASSERT_ERRNO_EQ(EINVAL);
}
@@ -45,23 +45,23 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// TODO: Look into collapsing these repeated segments.
const char *ten = "10";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(ten, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - ten, ptrdiff_t(2));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(ten, nullptr, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
const char *hundred = "100";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(hundred, &str_end, 10), ReturnT(100));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - hundred, ptrdiff_t(3));
const char *big_number = "1234567890";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(big_number, &str_end, 10), ReturnT(1234567890));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - big_number, ptrdiff_t(10));
@@ -69,7 +69,7 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// This number is larger than 2^32, meaning that if long is only 32 bits
// wide, strtol will return LONG_MAX.
const char *bigger_number = "12345678900";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
if constexpr (sizeof(ReturnT) < 8) {
ASSERT_EQ(func(bigger_number, &str_end, 10), T_MAX);
ASSERT_ERRNO_EQ(ERANGE);
@@ -80,14 +80,14 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
EXPECT_EQ(str_end - bigger_number, ptrdiff_t(11));
const char *too_big_number = "123456789012345678901";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(too_big_number, &str_end, 10), T_MAX);
ASSERT_ERRNO_EQ(ERANGE);
EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21));
const char *long_number_range_test =
"10000000000000000000000000000000000000000000000000";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(long_number_range_test, &str_end, 10), T_MAX);
ASSERT_ERRNO_EQ(ERANGE);
EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50));
@@ -95,19 +95,19 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// For most negative numbers, the unsigned functions treat it the same as
// casting a negative variable to an unsigned type.
const char *negative = "-100";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(negative, &str_end, 10), ReturnT(-100));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - negative, ptrdiff_t(4));
const char *big_negative_number = "-1234567890";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(big_negative_number, &str_end, 10), ReturnT(-1234567890));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(11));
const char *too_big_negative_number = "-123456789012345678901";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// If the number is signed, it should return the smallest negative number
// for the current type, but if it's unsigned it should max out and return
// the largest positive number for the current type. From the standard:
@@ -125,73 +125,73 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
char *str_end = nullptr;
const char *spaces_before = " 10";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(spaces_before, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7));
const char *spaces_after = "10 ";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(spaces_after, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2));
const char *word_before = "word10";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(word_before, &str_end, 10), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - word_before, ptrdiff_t(0));
const char *word_after = "10word";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(word_after, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - word_after, ptrdiff_t(2));
const char *two_numbers = "10 999";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(two_numbers, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2));
const char *two_signs = "--10 999";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(two_signs, &str_end, 10), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - two_signs, ptrdiff_t(0));
const char *sign_before = "+2=4";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(sign_before, &str_end, 10), ReturnT(2));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - sign_before, ptrdiff_t(2));
const char *sign_after = "2+2=4";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(sign_after, &str_end, 10), ReturnT(2));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - sign_after, ptrdiff_t(1));
const char *tab_before = "\t10";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(tab_before, &str_end, 10), ReturnT(10));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - tab_before, ptrdiff_t(3));
const char *all_together = "\t -12345and+67890";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(all_together, &str_end, 10), ReturnT(-12345));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - all_together, ptrdiff_t(9));
const char *just_spaces = " ";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_spaces, &str_end, 10), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0));
const char *just_space_and_sign = " +";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_space_and_sign, &str_end, 10), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0));
@@ -209,12 +209,12 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
for (int first_digit = 0; first_digit <= 36; ++first_digit) {
small_string[0] = int_to_b36_char(first_digit);
if (first_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base),
static_cast<ReturnT>(first_digit));
ASSERT_ERRNO_SUCCESS();
} else {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
}
@@ -227,18 +227,18 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
for (int second_digit = 0; second_digit <= 36; ++second_digit) {
small_string[1] = int_to_b36_char(second_digit);
if (first_digit < base && second_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(
func(small_string, nullptr, base),
static_cast<ReturnT>(second_digit + (first_digit * base)));
ASSERT_ERRNO_SUCCESS();
} else if (first_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base),
static_cast<ReturnT>(first_digit));
ASSERT_ERRNO_SUCCESS();
} else {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
}
@@ -256,14 +256,14 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
if (first_digit < base && second_digit < base &&
third_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base),
static_cast<ReturnT>(third_digit +
(second_digit * base) +
(first_digit * base * base)));
ASSERT_ERRNO_SUCCESS();
} else if (first_digit < base && second_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(
func(small_string, nullptr, base),
static_cast<ReturnT>(second_digit + (first_digit * base)));
@@ -273,23 +273,23 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// The number is treated as a one digit hexadecimal.
if (base == 16 && first_digit == 0 && second_digit == 33) {
if (third_digit < base) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base),
static_cast<ReturnT>(third_digit));
ASSERT_ERRNO_SUCCESS();
} else {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
}
} else {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base),
static_cast<ReturnT>(first_digit));
ASSERT_ERRNO_SUCCESS();
}
} else {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
}
@@ -303,19 +303,19 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
char *str_end = nullptr;
const char *no_prefix = "123abc";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(no_prefix, &str_end, 16), ReturnT(0x123abc));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6));
const char *yes_prefix = "0x456def";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(yes_prefix, &str_end, 16), ReturnT(0x456def));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8));
const char *letter_after_prefix = "0xabc123";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(letter_after_prefix, &str_end, 16), ReturnT(0xabc123));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8));
@@ -326,35 +326,33 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// Max size for unsigned 32 bit numbers
const char *max_32_bit_value = "0xFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(max_32_bit_value, &str_end, 0),
((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)
? T_MAX
: ReturnT(0xFFFFFFFF)));
- ASSERT_EQ(libc_errno,
- is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);
+ ASSERT_ERRNO_EQ(is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);
EXPECT_EQ(str_end - max_32_bit_value, ptrdiff_t(10));
const char *negative_max_32_bit_value = "-0xFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(negative_max_32_bit_value, &str_end, 0),
((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)
? T_MIN
: -ReturnT(0xFFFFFFFF)));
- ASSERT_EQ(libc_errno,
- is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);
+ ASSERT_ERRNO_EQ(is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);
EXPECT_EQ(str_end - negative_max_32_bit_value, ptrdiff_t(11));
// Max size for signed 32 bit numbers
const char *max_31_bit_value = "0x7FFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(max_31_bit_value, &str_end, 0), ReturnT(0x7FFFFFFF));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - max_31_bit_value, ptrdiff_t(10));
const char *negative_max_31_bit_value = "-0x7FFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(negative_max_31_bit_value, &str_end, 0),
-ReturnT(0x7FFFFFFF));
ASSERT_ERRNO_SUCCESS();
@@ -363,39 +361,37 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
// Max size for unsigned 64 bit numbers
const char *max_64_bit_value = "0xFFFFFFFFFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(max_64_bit_value, &str_end, 0),
(is_signed_v<ReturnT> || sizeof(ReturnT) < 8
? T_MAX
: ReturnT(0xFFFFFFFFFFFFFFFF)));
- ASSERT_EQ(libc_errno,
- (is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));
+ ASSERT_ERRNO_EQ((is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));
EXPECT_EQ(str_end - max_64_bit_value, ptrdiff_t(18));
// See the end of CleanBase10Decode for an explanation of how this large
// negative number can end up as T_MAX.
const char *negative_max_64_bit_value = "-0xFFFFFFFFFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(
func(negative_max_64_bit_value, &str_end, 0),
(is_signed_v<ReturnT>
? T_MIN
: (sizeof(ReturnT) < 8 ? T_MAX : -ReturnT(0xFFFFFFFFFFFFFFFF))));
- ASSERT_EQ(libc_errno,
- (is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));
+ ASSERT_ERRNO_EQ((is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));
EXPECT_EQ(str_end - negative_max_64_bit_value, ptrdiff_t(19));
// Max size for signed 64 bit numbers
const char *max_63_bit_value = "0x7FFFFFFFFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(max_63_bit_value, &str_end, 0),
(sizeof(ReturnT) < 8 ? T_MAX : ReturnT(0x7FFFFFFFFFFFFFFF)));
ASSERT_ERRNO_EQ(sizeof(ReturnT) < 8 ? ERANGE : 0);
EXPECT_EQ(str_end - max_63_bit_value, ptrdiff_t(18));
const char *negative_max_63_bit_value = "-0x7FFFFFFFFFFFFFFF";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(negative_max_63_bit_value, &str_end, 0),
(sizeof(ReturnT) >= 8 ? -ReturnT(0x7FFFFFFFFFFFFFFF)
: (is_signed_v<ReturnT> ? T_MIN : T_MAX)));
@@ -407,23 +403,23 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
char *str_end = nullptr;
const char *just_prefix = "0x";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_prefix, &str_end, 16), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_prefix, &str_end, 0), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1));
const char *prefix_with_x_after = "0xx";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(prefix_with_x_after, &str_end, 16), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(prefix_with_x_after, &str_end, 0), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1));
@@ -433,43 +429,43 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test {
char *str_end = nullptr;
const char *base_ten = "12345";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(base_ten, &str_end, 0), ReturnT(12345));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - base_ten, ptrdiff_t(5));
const char *base_sixteen_no_prefix = "123abc";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(base_sixteen_no_prefix, &str_end, 0), ReturnT(123));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3));
const char *base_sixteen_with_prefix = "0x456def";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(base_sixteen_with_prefix, &str_end, 0), ReturnT(0x456def));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8));
const char *base_eight_with_prefix = "012345";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(base_eight_with_prefix, &str_end, 0), ReturnT(012345));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6));
const char *just_zero = "0";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_zero, &str_end, 0), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_zero, ptrdiff_t(1));
const char *just_zero_x = "0x";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_zero_x, &str_end, 0), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1));
const char *just_zero_eight = "08";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(func(just_zero_eight, &str_end, 0), ReturnT(0));
ASSERT_ERRNO_SUCCESS();
EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1));
diff --git a/test/src/stdlib/atof_test.cpp b/test/src/stdlib/atof_test.cpp
index 858ab326e38d..1e4259b792d7 100644
--- a/test/src/stdlib/atof_test.cpp
+++ b/test/src/stdlib/atof_test.cpp
@@ -23,13 +23,13 @@ TEST(LlvmLibcAToFTest, SimpleTest) {
LIBC_NAMESPACE::fputil::FPBits<double> expected_fp =
LIBC_NAMESPACE::fputil::FPBits<double>(uint64_t(0x405ec00000000000));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_THAT(LIBC_NAMESPACE::atof("123"),
Succeeds<double>(expected_fp.get_val()));
}
TEST(LlvmLibcAToFTest, FailedParsingTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// atof does not flag errors.
EXPECT_THAT(LIBC_NAMESPACE::atof("???"), Succeeds<double>(0.0));
}
diff --git a/test/src/stdlib/strfromd_test.cpp b/test/src/stdlib/strfromd_test.cpp
new file mode 100644
index 000000000000..55724d7e902b
--- /dev/null
+++ b/test/src/stdlib/strfromd_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for strfromd --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "StrfromTest.h"
+#include "src/stdlib/strfromd.h"
+#include "test/UnitTest/Test.h"
+
+STRFROM_TEST(double, Strfromd, LIBC_NAMESPACE::strfromd)
diff --git a/test/src/stdlib/strfromf_test.cpp b/test/src/stdlib/strfromf_test.cpp
new file mode 100644
index 000000000000..8b987fd434ac
--- /dev/null
+++ b/test/src/stdlib/strfromf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for strfromf --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "StrfromTest.h"
+#include "src/stdlib/strfromf.h"
+#include "test/UnitTest/Test.h"
+
+STRFROM_TEST(float, StrFromf, LIBC_NAMESPACE::strfromf)
diff --git a/test/src/stdlib/strfroml_test.cpp b/test/src/stdlib/strfroml_test.cpp
new file mode 100644
index 000000000000..cf472a39a5bf
--- /dev/null
+++ b/test/src/stdlib/strfroml_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for strfroml --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "StrfromTest.h"
+#include "src/stdlib/strfroml.h"
+#include "test/UnitTest/Test.h"
+
+STRFROM_TEST(long double, Strfroml, LIBC_NAMESPACE::strfroml)
diff --git a/test/src/stdlib/strtod_test.cpp b/test/src/stdlib/strtod_test.cpp
index e68c8610b407..92d14640e653 100644
--- a/test/src/stdlib/strtod_test.cpp
+++ b/test/src/stdlib/strtod_test.cpp
@@ -46,7 +46,7 @@ public:
LIBC_NAMESPACE::fputil::FPBits<double> expected_fp =
LIBC_NAMESPACE::fputil::FPBits<double>(expectedRawData);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
double result = LIBC_NAMESPACE::strtod(inputString, &str_end);
if (expectedErrno == 0)
EXPECT_THAT(result, Succeeds<double>(expected_fp.get_val()));
diff --git a/test/src/stdlib/strtof_test.cpp b/test/src/stdlib/strtof_test.cpp
index b43c32f90261..d7991745b69e 100644
--- a/test/src/stdlib/strtof_test.cpp
+++ b/test/src/stdlib/strtof_test.cpp
@@ -43,7 +43,7 @@ public:
LIBC_NAMESPACE::fputil::FPBits<float> expected_fp =
LIBC_NAMESPACE::fputil::FPBits<float>(expectedRawData);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
float result = LIBC_NAMESPACE::strtof(inputString, &str_end);
EXPECT_EQ(str_end - inputString, expectedStrLen);
diff --git a/test/src/stdlib/strtoint32_test.cpp b/test/src/stdlib/strtoint32_test.cpp
index 4ca20f3333f5..a7c9141d9f79 100644
--- a/test/src/stdlib/strtoint32_test.cpp
+++ b/test/src/stdlib/strtoint32_test.cpp
@@ -20,7 +20,7 @@ int32_t strtoint32(const char *__restrict str, char **__restrict str_end,
int base) {
auto result = internal::strtointeger<int32_t>(str, base);
if (result.has_error())
- libc_errno = result.error;
+ LIBC_NAMESPACE::libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
@@ -32,7 +32,7 @@ uint32_t strtouint32(const char *__restrict str, char **__restrict str_end,
int base) {
auto result = internal::strtointeger<uint32_t>(str, base);
if (result.has_error())
- libc_errno = result.error;
+ LIBC_NAMESPACE::libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
diff --git a/test/src/stdlib/strtoint64_test.cpp b/test/src/stdlib/strtoint64_test.cpp
index f8d807b146f2..350b5aca4c85 100644
--- a/test/src/stdlib/strtoint64_test.cpp
+++ b/test/src/stdlib/strtoint64_test.cpp
@@ -20,7 +20,7 @@ int64_t strtoint64(const char *__restrict str, char **__restrict str_end,
int base) {
auto result = internal::strtointeger<int64_t>(str, base);
if (result.has_error())
- libc_errno = result.error;
+ LIBC_NAMESPACE::libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
@@ -32,7 +32,7 @@ uint64_t strtouint64(const char *__restrict str, char **__restrict str_end,
int base) {
auto result = internal::strtointeger<uint64_t>(str, base);
if (result.has_error())
- libc_errno = result.error;
+ LIBC_NAMESPACE::libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
diff --git a/test/src/stdlib/strtold_test.cpp b/test/src/stdlib/strtold_test.cpp
index cbe0a47b9b71..2066e9635aba 100644
--- a/test/src/stdlib/strtold_test.cpp
+++ b/test/src/stdlib/strtold_test.cpp
@@ -15,17 +15,19 @@
#include <stddef.h>
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
#define SELECT_CONST(val, _, __) val
-#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#define SELECT_CONST(_, val, __) val
-#else
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
#define SELECT_CONST(_, __, val) val
+#else
+#error "Unknown long double type"
#endif
class LlvmLibcStrToLDTest : public LIBC_NAMESPACE::testing::Test {
public:
-#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
const uint64_t expectedRawData, const int expectedErrno = 0)
#else
@@ -77,7 +79,7 @@ public:
LIBC_NAMESPACE::fputil::FPBits<long double>(expectedRawData);
const int expected_errno = expectedErrno;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
long double result = LIBC_NAMESPACE::strtold(inputString, &str_end);
LIBC_NAMESPACE::fputil::FPBits<long double> actual_fp =
diff --git a/test/src/string/memory_utils/op_tests.cpp b/test/src/string/memory_utils/op_tests.cpp
index 15ac9607bf3e..703a26b16b03 100644
--- a/test/src/string/memory_utils/op_tests.cpp
+++ b/test/src/string/memory_utils/op_tests.cpp
@@ -7,9 +7,10 @@
//===----------------------------------------------------------------------===//
#include "memory_check_utils.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT64
#include "src/string/memory_utils/op_aarch64.h"
#include "src/string/memory_utils/op_builtin.h"
-#include "src/string/memory_utils/op_generic.h" // LLVM_LIBC_HAS_UINT64
+#include "src/string/memory_utils/op_generic.h"
#include "src/string/memory_utils/op_riscv.h"
#include "src/string/memory_utils/op_x86.h"
#include "test/UnitTest/Test.h"
@@ -124,9 +125,9 @@ using MemsetImplementations = testing::TypeList<
builtin::Memset<32>, //
builtin::Memset<64>,
#endif
-#ifdef LLVM_LIBC_HAS_UINT64
+#ifdef LIBC_TYPES_HAS_INT64
generic::Memset<uint64_t>, generic::Memset<cpp::array<uint64_t, 2>>,
-#endif
+#endif // LIBC_TYPES_HAS_INT64
#ifdef __AVX512F__
generic::Memset<generic_v512>, generic::Memset<cpp::array<generic_v512, 2>>,
#endif
@@ -210,9 +211,9 @@ using BcmpImplementations = testing::TypeList<
#ifndef LIBC_TARGET_ARCH_IS_ARM // Removing non uint8_t types for ARM
generic::Bcmp<uint16_t>,
generic::Bcmp<uint32_t>, //
-#ifdef LLVM_LIBC_HAS_UINT64
+#ifdef LIBC_TYPES_HAS_INT64
generic::Bcmp<uint64_t>,
-#endif // LLVM_LIBC_HAS_UINT64
+#endif // LIBC_TYPES_HAS_INT64
generic::BcmpSequence<uint16_t, uint8_t>,
generic::BcmpSequence<uint32_t, uint8_t>, //
generic::BcmpSequence<uint32_t, uint16_t>, //
@@ -292,9 +293,9 @@ using MemcmpImplementations = testing::TypeList<
#ifndef LIBC_TARGET_ARCH_IS_ARM // Removing non uint8_t types for ARM
generic::Memcmp<uint16_t>,
generic::Memcmp<uint32_t>, //
-#ifdef LLVM_LIBC_HAS_UINT64
+#ifdef LIBC_TYPES_HAS_INT64
generic::Memcmp<uint64_t>,
-#endif // LLVM_LIBC_HAS_UINT64
+#endif // LIBC_TYPES_HAS_INT64
generic::MemcmpSequence<uint16_t, uint8_t>,
generic::MemcmpSequence<uint32_t, uint16_t, uint8_t>, //
#endif // LIBC_TARGET_ARCH_IS_ARM
diff --git a/test/src/string/memset_explicit_test.cpp b/test/src/string/memset_explicit_test.cpp
new file mode 100644
index 000000000000..bb5111bd639e
--- /dev/null
+++ b/test/src/string/memset_explicit_test.cpp
@@ -0,0 +1,31 @@
+//===-- Unittests for memset_explicit -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "memory_utils/memory_check_utils.h"
+#include "src/string/memset_explicit.h"
+#include "test/UnitTest/Test.h"
+
+namespace LIBC_NAMESPACE {
+
+// Apply the same tests as memset
+
+static inline void Adaptor(cpp::span<char> p1, uint8_t value, size_t size) {
+ LIBC_NAMESPACE::memset_explicit(p1.begin(), value, size);
+}
+
+TEST(LlvmLibcmemsetExplicitTest, SizeSweep) {
+ static constexpr size_t kMaxSize = 400;
+ Buffer DstBuffer(kMaxSize);
+ for (size_t size = 0; size < kMaxSize; ++size) {
+ const char value = size % 10;
+ auto dst = DstBuffer.span().subspan(0, size);
+ ASSERT_TRUE((CheckMemset<Adaptor>(dst, value, size)));
+ }
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/test/src/string/strdup_test.cpp b/test/src/string/strdup_test.cpp
index caf8c2e61c0e..fd3cceaaa17c 100644
--- a/test/src/string/strdup_test.cpp
+++ b/test/src/string/strdup_test.cpp
@@ -15,7 +15,7 @@
TEST(LlvmLibcStrDupTest, EmptyString) {
const char *empty = "";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
char *result = LIBC_NAMESPACE::strdup(empty);
ASSERT_ERRNO_SUCCESS();
@@ -28,7 +28,7 @@ TEST(LlvmLibcStrDupTest, EmptyString) {
TEST(LlvmLibcStrDupTest, AnyString) {
const char *abc = "abc";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
char *result = LIBC_NAMESPACE::strdup(abc);
ASSERT_ERRNO_SUCCESS();
@@ -39,7 +39,7 @@ TEST(LlvmLibcStrDupTest, AnyString) {
}
TEST(LlvmLibcStrDupTest, NullPtr) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
char *result = LIBC_NAMESPACE::strdup(nullptr);
ASSERT_ERRNO_SUCCESS();
diff --git a/test/src/sys/epoll/linux/epoll_pwait2_test.cpp b/test/src/sys/epoll/linux/epoll_pwait2_test.cpp
new file mode 100644
index 000000000000..83fe12bb8eb6
--- /dev/null
+++ b/test/src/sys/epoll/linux/epoll_pwait2_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for epoll_pwait2 ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/errno/libc_errno.h"
+#include "src/sys/epoll/epoll_pwait2.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcEpollWaitTest, Basic) {
+ EXPECT_THAT(LIBC_NAMESPACE::epoll_pwait2(-1, nullptr, 0, nullptr, nullptr),
+ returns(EQ(-1ul)).with_errno(EQ(EINVAL)));
+}
+
+// TODO: Complete these tests when epoll_create is implemented.
diff --git a/test/src/sys/epoll/linux/epoll_pwait_test.cpp b/test/src/sys/epoll/linux/epoll_pwait_test.cpp
new file mode 100644
index 000000000000..217facbfcebb
--- /dev/null
+++ b/test/src/sys/epoll/linux/epoll_pwait_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for epoll_pwait -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/errno/libc_errno.h"
+#include "src/sys/epoll/epoll_pwait.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcEpollWaitTest, Basic) {
+ EXPECT_THAT(LIBC_NAMESPACE::epoll_pwait(-1, nullptr, 0, 0, nullptr),
+ returns(EQ(-1ul)).with_errno(EQ(EINVAL)));
+}
+
+// TODO: Complete these tests when epoll_create is implemented.
diff --git a/test/src/sys/epoll/linux/epoll_wait_test.cpp b/test/src/sys/epoll/linux/epoll_wait_test.cpp
new file mode 100644
index 000000000000..57fef3f690b6
--- /dev/null
+++ b/test/src/sys/epoll/linux/epoll_wait_test.cpp
@@ -0,0 +1,20 @@
+//===-- Unittests for epoll_wait ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/errno/libc_errno.h"
+#include "src/sys/epoll/epoll_wait.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcEpollWaitTest, Basic) {
+ EXPECT_THAT(LIBC_NAMESPACE::epoll_wait(-1, nullptr, 0, 0),
+ returns(EQ(-1ul)).with_errno(EQ(EINVAL)));
+}
+
+// TODO: Complete these tests when epoll_create is implemented.
diff --git a/test/src/sys/mman/linux/madvise_test.cpp b/test/src/sys/mman/linux/madvise_test.cpp
index 83c73f5454de..6768d111c0d9 100644
--- a/test/src/sys/mman/linux/madvise_test.cpp
+++ b/test/src/sys/mman/linux/madvise_test.cpp
@@ -20,10 +20,10 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcMadviseTest, NoError) {
size_t alloc_size = 128;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(0, libc_errno);
+ ASSERT_ERRNO_SUCCESS();
EXPECT_NE(addr, MAP_FAILED);
EXPECT_THAT(LIBC_NAMESPACE::madvise(addr, alloc_size, MADV_RANDOM),
@@ -38,7 +38,7 @@ TEST(LlvmLibcMadviseTest, NoError) {
}
TEST(LlvmLibcMadviseTest, Error_BadPtr) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_THAT(LIBC_NAMESPACE::madvise(nullptr, 8, MADV_SEQUENTIAL),
Fails(ENOMEM));
}
diff --git a/test/src/sys/mman/linux/mincore_test.cpp b/test/src/sys/mman/linux/mincore_test.cpp
index 493d748f2c98..8e0c29c2ac17 100644
--- a/test/src/sys/mman/linux/mincore_test.cpp
+++ b/test/src/sys/mman/linux/mincore_test.cpp
@@ -10,7 +10,9 @@
#include "src/errno/libc_errno.h"
#include "src/sys/mman/madvise.h"
#include "src/sys/mman/mincore.h"
+#include "src/sys/mman/mlock.h"
#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munlock.h"
#include "src/sys/mman/munmap.h"
#include "src/unistd/sysconf.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
@@ -25,7 +27,7 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcMincoreTest, UnMappedMemory) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
unsigned char vec;
int res = LIBC_NAMESPACE::mincore(nullptr, 1, &vec);
EXPECT_THAT(res, Fails(ENOMEM, -1));
@@ -37,7 +39,7 @@ TEST(LlvmLibcMincoreTest, UnalignedAddr) {
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
EXPECT_NE(addr, MAP_FAILED);
EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int res = LIBC_NAMESPACE::mincore(static_cast<char *>(addr) + 1, 1, nullptr);
EXPECT_THAT(res, Fails(EINVAL, -1));
EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
@@ -49,7 +51,7 @@ TEST(LlvmLibcMincoreTest, InvalidVec) {
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
EXPECT_NE(addr, MAP_FAILED);
EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int res = LIBC_NAMESPACE::mincore(addr, 1, nullptr);
EXPECT_THAT(res, Fails(EFAULT, -1));
}
@@ -61,7 +63,7 @@ TEST(LlvmLibcMincoreTest, NoError) {
EXPECT_NE(addr, MAP_FAILED);
EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
unsigned char vec;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
EXPECT_THAT(res, Succeeds());
EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
@@ -74,7 +76,7 @@ TEST(LlvmLibcMincoreTest, NegativeLength) {
EXPECT_NE(addr, MAP_FAILED);
EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
unsigned char vec;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int res = LIBC_NAMESPACE::mincore(addr, -1, &vec);
EXPECT_THAT(res, Fails(ENOMEM, -1));
EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
@@ -91,25 +93,20 @@ TEST(LlvmLibcMincoreTest, PageOut) {
// touch the page
{
static_cast<char *>(addr)[0] = 0;
- // TODO: use wrapper functions for mlock/munlock once implemented.
- // See issue https://github.com/llvm/llvm-project/issues/79336
- LIBC_NAMESPACE::syscall_impl(
- SYS_mlock, reinterpret_cast<unsigned long>(addr), page_size);
- libc_errno = 0;
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(addr, page_size), Succeeds());
int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
EXPECT_EQ(vec & 1u, 1u);
EXPECT_THAT(res, Succeeds());
- LIBC_NAMESPACE::syscall_impl(
- SYS_munlock, reinterpret_cast<unsigned long>(addr), page_size);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(addr, page_size), Succeeds());
}
// page out the memory
{
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_THAT(LIBC_NAMESPACE::madvise(addr, page_size, MADV_DONTNEED),
Succeeds());
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int res = LIBC_NAMESPACE::mincore(addr, page_size, &vec);
EXPECT_EQ(vec & 1u, 0u);
EXPECT_THAT(res, Succeeds());
diff --git a/test/src/sys/mman/linux/mlock_test.cpp b/test/src/sys/mman/linux/mlock_test.cpp
new file mode 100644
index 000000000000..804038a68a7e
--- /dev/null
+++ b/test/src/sys/mman/linux/mlock_test.cpp
@@ -0,0 +1,203 @@
+//===-- Unittests for mlock -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/OSUtil/syscall.h" // For internal syscall function.
+#include "src/errno/libc_errno.h"
+#include "src/sys/mman/madvise.h"
+#include "src/sys/mman/mincore.h"
+#include "src/sys/mman/mlock.h"
+#include "src/sys/mman/mlock2.h"
+#include "src/sys/mman/mlockall.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munlock.h"
+#include "src/sys/mman/munlockall.h"
+#include "src/sys/mman/munmap.h"
+#include "src/sys/resource/getrlimit.h"
+#include "src/unistd/sysconf.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include "test/UnitTest/Test.h"
+
+#include <asm-generic/errno-base.h>
+#include <asm-generic/mman.h>
+#include <linux/capability.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+struct PageHolder {
+ size_t size;
+ void *addr;
+
+ PageHolder()
+ : size(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE)),
+ addr(LIBC_NAMESPACE::mmap(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) {}
+ ~PageHolder() {
+ if (addr != MAP_FAILED)
+ LIBC_NAMESPACE::munmap(addr, size);
+ }
+
+ char &operator[](size_t i) { return reinterpret_cast<char *>(addr)[i]; }
+
+ bool is_valid() { return addr != MAP_FAILED; }
+};
+
+static bool get_capacity(unsigned int cap) {
+ __user_cap_header_struct header;
+ header.pid = 0;
+ header.version = _LINUX_CAPABILITY_VERSION_3;
+ __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
+ // TODO: use capget wrapper once implemented.
+ // https://github.com/llvm/llvm-project/issues/80037
+ long res = LIBC_NAMESPACE::syscall_impl(
+ SYS_capget, LIBC_NAMESPACE::cpp::bit_cast<long>(&header),
+ LIBC_NAMESPACE::cpp::bit_cast<long>(&data));
+ if (res < 0)
+ return false;
+ unsigned idx = CAP_TO_INDEX(cap);
+ unsigned shift = CAP_TO_MASK(cap);
+ return (data[idx].effective & shift) != 0;
+}
+
+static bool is_permitted_size(size_t size) {
+ rlimit rlimits;
+ LIBC_NAMESPACE::getrlimit(RLIMIT_MEMLOCK, &rlimits);
+ return size <= static_cast<size_t>(rlimits.rlim_cur) ||
+ get_capacity(CAP_IPC_LOCK);
+}
+
+TEST(LlvmLibcMlockTest, UnMappedMemory) {
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(nullptr, 1024), Fails(ENOMEM));
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(nullptr, 1024), Fails(ENOMEM));
+}
+
+TEST(LlvmLibcMlockTest, Overflow) {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ size_t negative_size = -holder.size;
+ int expected_errno = is_permitted_size(negative_size) ? EINVAL : ENOMEM;
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, negative_size),
+ Fails(expected_errno));
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, negative_size),
+ Fails(EINVAL));
+}
+
+#ifdef SYS_mlock2
+TEST(LlvmLibcMlockTest, MLock2) {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ EXPECT_THAT(LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(holder.addr, holder.size, 0), Succeeds());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, holder.size), Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(holder.addr, holder.size, MLOCK_ONFAULT),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 0);
+ holder[0] = 1;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, holder.size), Succeeds());
+}
+#endif
+
+TEST(LlvmLibcMlockTest, InvalidFlag) {
+ size_t alloc_size = 128; // page size
+ LIBC_NAMESPACE::libc_errno = 0;
+ void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ ASSERT_ERRNO_SUCCESS();
+ EXPECT_NE(addr, MAP_FAILED);
+
+ // Invalid mlock2 flags.
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(addr, alloc_size, 1234), Fails(EINVAL));
+
+ // Invalid mlockall flags.
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(1234), Fails(EINVAL));
+
+ // man 2 mlockall says EINVAL is a valid return code when MCL_ONFAULT was
+ // specified without MCL_FUTURE or MCL_CURRENT, but this seems to fail on
+ // Linux 4.19.y (EOL).
+ // TODO(ndesaulniers) re-enable after
+ // https://github.com/llvm/llvm-project/issues/80073 is fixed.
+ // EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_ONFAULT), Fails(EINVAL));
+
+ LIBC_NAMESPACE::munmap(addr, alloc_size);
+}
+
+TEST(LlvmLibcMlockTest, MLockAll) {
+ {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ EXPECT_THAT(
+ LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_CURRENT);
+ if (retval == -1) {
+ EXPECT_TRUE(LIBC_NAMESPACE::libc_errno == ENOMEM ||
+ LIBC_NAMESPACE::libc_errno == EPERM);
+ LIBC_NAMESPACE::libc_errno = 0;
+ return;
+ }
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+ {
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE);
+ if (retval == -1) {
+ EXPECT_TRUE(LIBC_NAMESPACE::libc_errno == ENOMEM ||
+ LIBC_NAMESPACE::libc_errno == EPERM);
+ LIBC_NAMESPACE::libc_errno = 0;
+ return;
+ }
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+#ifdef MCL_ONFAULT
+ {
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT);
+ if (retval == -1) {
+ EXPECT_TRUE(LIBC_NAMESPACE::libc_errno == ENOMEM ||
+ LIBC_NAMESPACE::libc_errno == EPERM);
+ LIBC_NAMESPACE::libc_errno = 0;
+ return;
+ }
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 0);
+ holder[0] = 1;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+#endif
+}
diff --git a/test/src/sys/mman/linux/mmap_test.cpp b/test/src/sys/mman/linux/mmap_test.cpp
index 9b13b8bd8057..dcbc75808f13 100644
--- a/test/src/sys/mman/linux/mmap_test.cpp
+++ b/test/src/sys/mman/linux/mmap_test.cpp
@@ -19,10 +19,10 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcMMapTest, NoError) {
size_t alloc_size = 128;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(0, libc_errno);
+ ASSERT_ERRNO_SUCCESS();
EXPECT_NE(addr, MAP_FAILED);
int *array = reinterpret_cast<int *>(addr);
@@ -34,7 +34,7 @@ TEST(LlvmLibcMMapTest, NoError) {
}
TEST(LlvmLibcMMapTest, Error_InvalidSize) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
void *addr = LIBC_NAMESPACE::mmap(nullptr, 0, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
EXPECT_THAT(addr, Fails(EINVAL, MAP_FAILED));
diff --git a/test/src/sys/mman/linux/mprotect_test.cpp b/test/src/sys/mman/linux/mprotect_test.cpp
index 7127f77714d6..46e449e54779 100644
--- a/test/src/sys/mman/linux/mprotect_test.cpp
+++ b/test/src/sys/mman/linux/mprotect_test.cpp
@@ -21,10 +21,10 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcMProtectTest, NoError) {
size_t alloc_size = 128;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(0, libc_errno);
+ ASSERT_ERRNO_SUCCESS();
EXPECT_NE(addr, MAP_FAILED);
int *array = reinterpret_cast<int *>(addr);
diff --git a/test/src/sys/mman/linux/msync_test.cpp b/test/src/sys/mman/linux/msync_test.cpp
new file mode 100644
index 000000000000..0d60415b1243
--- /dev/null
+++ b/test/src/sys/mman/linux/msync_test.cpp
@@ -0,0 +1,69 @@
+//===-- Unittests for msync -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/errno/libc_errno.h"
+#include "src/sys/mman/mlock.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/msync.h"
+#include "src/sys/mman/munlock.h"
+#include "src/sys/mman/munmap.h"
+#include "src/unistd/sysconf.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+struct PageHolder {
+ size_t size;
+ void *addr;
+
+ PageHolder()
+ : size(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE)),
+ addr(LIBC_NAMESPACE::mmap(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) {}
+ ~PageHolder() {
+ if (addr != MAP_FAILED)
+ LIBC_NAMESPACE::munmap(addr, size);
+ }
+
+ char &operator[](size_t i) { return reinterpret_cast<char *>(addr)[i]; }
+
+ bool is_valid() { return addr != MAP_FAILED; }
+};
+
+TEST(LlvmLibcMsyncTest, UnMappedMemory) {
+ EXPECT_THAT(LIBC_NAMESPACE::msync(nullptr, 1024, MS_SYNC), Fails(ENOMEM));
+ EXPECT_THAT(LIBC_NAMESPACE::msync(nullptr, 1024, MS_ASYNC), Fails(ENOMEM));
+}
+
+TEST(LlvmLibcMsyncTest, LockedPage) {
+ PageHolder page;
+ ASSERT_TRUE(page.is_valid());
+ ASSERT_THAT(LIBC_NAMESPACE::mlock(page.addr, page.size), Succeeds());
+ EXPECT_THAT(
+ LIBC_NAMESPACE::msync(page.addr, page.size, MS_SYNC | MS_INVALIDATE),
+ Fails(EBUSY));
+ ASSERT_THAT(LIBC_NAMESPACE::munlock(page.addr, page.size), Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::msync(page.addr, page.size, MS_SYNC), Succeeds());
+}
+
+TEST(LlvmLibcMsyncTest, UnalignedAddress) {
+ PageHolder page;
+ ASSERT_TRUE(page.is_valid());
+ EXPECT_THAT(LIBC_NAMESPACE::msync(&page[1], page.size - 1, MS_SYNC),
+ Fails(EINVAL));
+}
+
+TEST(LlvmLibcMsyncTest, InvalidFlag) {
+ PageHolder page;
+ ASSERT_TRUE(page.is_valid());
+ EXPECT_THAT(LIBC_NAMESPACE::msync(page.addr, page.size, MS_SYNC | MS_ASYNC),
+ Fails(EINVAL));
+ EXPECT_THAT(LIBC_NAMESPACE::msync(page.addr, page.size, -1), Fails(EINVAL));
+}
diff --git a/test/src/sys/mman/linux/posix_madvise_test.cpp b/test/src/sys/mman/linux/posix_madvise_test.cpp
index 59cf01ac7469..ee6489c5ed2f 100644
--- a/test/src/sys/mman/linux/posix_madvise_test.cpp
+++ b/test/src/sys/mman/linux/posix_madvise_test.cpp
@@ -20,10 +20,10 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcPosixMadviseTest, NoError) {
size_t alloc_size = 128;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(0, libc_errno);
+ ASSERT_ERRNO_SUCCESS();
EXPECT_NE(addr, MAP_FAILED);
EXPECT_EQ(LIBC_NAMESPACE::posix_madvise(addr, alloc_size, POSIX_MADV_RANDOM),
@@ -38,7 +38,7 @@ TEST(LlvmLibcPosixMadviseTest, NoError) {
}
TEST(LlvmLibcPosixMadviseTest, Error_BadPtr) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// posix_madvise is a no-op on DONTNEED, so it shouldn't fail even with the
// nullptr.
EXPECT_EQ(LIBC_NAMESPACE::posix_madvise(nullptr, 8, POSIX_MADV_DONTNEED), 0);
diff --git a/test/src/sys/mman/linux/shm_test.cpp b/test/src/sys/mman/linux/shm_test.cpp
new file mode 100644
index 000000000000..3b1a2aa33b56
--- /dev/null
+++ b/test/src/sys/mman/linux/shm_test.cpp
@@ -0,0 +1,77 @@
+//===-- Unittests for shm_open/shm_unlink ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/OSUtil/syscall.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munmap.h"
+#include "src/sys/mman/shm_open.h"
+#include "src/sys/mman/shm_unlink.h"
+#include "src/unistd/close.h"
+#include "src/unistd/ftruncate.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include <asm-generic/fcntl.h>
+#include <sys/syscall.h>
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+// since shm_open/shm_unlink are wrappers around open/unlink, we only focus on
+// testing basic cases and name conversions.
+
+TEST(LlvmLibcShmTest, Basic) {
+ const char *name = "/test_shm_open";
+ int fd;
+ ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666),
+ returns(GE(0)).with_errno(EQ(0)));
+
+ // check that FD_CLOEXEC is set by default.
+ // TODO: use fcntl when implemented.
+ // https://github.com/llvm/llvm-project/issues/84968
+ long flag = LIBC_NAMESPACE::syscall_impl(SYS_fcntl, fd, F_GETFD);
+ ASSERT_GE(static_cast<int>(flag), 0);
+ EXPECT_NE(static_cast<int>(flag) & FD_CLOEXEC, 0);
+
+ // allocate space using ftruncate
+ ASSERT_THAT(LIBC_NAMESPACE::ftruncate(fd, 4096), Succeeds());
+ // map the shared memory
+ void *addr = LIBC_NAMESPACE::mmap(nullptr, 4096, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ ASSERT_NE(addr, MAP_FAILED);
+ // just write random data to the shared memory
+ char data[] = "Despite its name, LLVM has little to do with traditional "
+ "virtual machines.";
+ for (size_t i = 0; i < sizeof(data); ++i)
+ static_cast<char *>(addr)[i] = data[i];
+
+ // close fd does not affect the mapping
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
+ for (size_t i = 0; i < sizeof(data); ++i)
+ EXPECT_EQ(static_cast<char *>(addr)[i], data[i]);
+
+ // unmap the shared memory
+ ASSERT_THAT(LIBC_NAMESPACE::munmap(addr, 4096), Succeeds());
+ // remove the shared memory
+ ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds());
+}
+
+TEST(LlvmLibcShmTest, NameConversion) {
+ const char *name = "////test_shm_open";
+ int fd;
+ ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666),
+ returns(GE(0)).with_errno(EQ(0)));
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
+ ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds());
+
+ ASSERT_THAT(LIBC_NAMESPACE::shm_open("/123/123", O_CREAT | O_RDWR, 0666),
+ Fails(EINVAL));
+
+ ASSERT_THAT(LIBC_NAMESPACE::shm_open("/.", O_CREAT | O_RDWR, 0666),
+ Fails(EINVAL));
+
+ ASSERT_THAT(LIBC_NAMESPACE::shm_open("/..", O_CREAT | O_RDWR, 0666),
+ Fails(EINVAL));
+}
diff --git a/test/src/sys/prctl/linux/prctl_test.cpp b/test/src/sys/prctl/linux/prctl_test.cpp
index 6278dcec588a..b528edc65595 100644
--- a/test/src/sys/prctl/linux/prctl_test.cpp
+++ b/test/src/sys/prctl/linux/prctl_test.cpp
@@ -34,7 +34,7 @@ TEST(LlvmLibcSysPrctlTest, GetSetName) {
TEST(LlvmLibcSysPrctlTest, GetTHPDisable) {
// Manually check errno since the return value logic here is not
// covered in ErrnoSetterMatcher.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int ret = LIBC_NAMESPACE::prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0);
ASSERT_ERRNO_SUCCESS();
// PR_GET_THP_DISABLE return (as the function result) the current
diff --git a/test/src/sys/random/linux/getrandom_test.cpp b/test/src/sys/random/linux/getrandom_test.cpp
index 5a595afb0cda..e3481b73ca00 100644
--- a/test/src/sys/random/linux/getrandom_test.cpp
+++ b/test/src/sys/random/linux/getrandom_test.cpp
@@ -15,13 +15,13 @@
TEST(LlvmLibcGetRandomTest, InvalidFlag) {
LIBC_NAMESPACE::cpp::array<char, 10> buffer;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::getrandom(buffer.data(), buffer.size(), -1),
LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails(EINVAL));
}
TEST(LlvmLibcGetRandomTest, InvalidBuffer) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::getrandom(nullptr, 65536, 0),
LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails(EFAULT));
}
diff --git a/test/src/sys/resource/getrlimit_setrlimit_test.cpp b/test/src/sys/resource/getrlimit_setrlimit_test.cpp
index 1a0d79f4e752..62d21c33e998 100644
--- a/test/src/sys/resource/getrlimit_setrlimit_test.cpp
+++ b/test/src/sys/resource/getrlimit_setrlimit_test.cpp
@@ -29,7 +29,7 @@ TEST(LlvmLibcResourceLimitsTest, SetNoFileLimit) {
constexpr const char *TEST_FILE1 = "testdata/resource_limits1.test";
constexpr const char *TEST_FILE2 = "testdata/resource_limits2.test";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd1 = LIBC_NAMESPACE::open(TEST_FILE1, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd1, 0);
@@ -54,7 +54,7 @@ TEST(LlvmLibcResourceLimitsTest, SetNoFileLimit) {
ASSERT_LT(fd2, 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::close(fd1), Succeeds(0));
fd2 = LIBC_NAMESPACE::open(TEST_FILE2, O_RDONLY);
@@ -64,7 +64,7 @@ TEST(LlvmLibcResourceLimitsTest, SetNoFileLimit) {
ASSERT_LT(fd1, 0);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::close(fd2), Succeeds(0));
ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE1), Succeeds(0));
diff --git a/test/src/sys/select/select_ui_test.cpp b/test/src/sys/select/select_ui_test.cpp
index 2e6baced801b..a158cab8ff05 100644
--- a/test/src/sys/select/select_ui_test.cpp
+++ b/test/src/sys/select/select_ui_test.cpp
@@ -18,7 +18,7 @@
// Instead, one has to run it manually and press a key on the keyboard
// to make the test succeed.
TEST(LlvmLibcSelectTest, ReadStdinAfterSelect) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
constexpr int STDIN_FD = 0;
fd_set set;
FD_ZERO(&set);
diff --git a/test/src/sys/sendfile/sendfile_test.cpp b/test/src/sys/sendfile/sendfile_test.cpp
index 5ea9ca8d05c5..59025438a246 100644
--- a/test/src/sys/sendfile/sendfile_test.cpp
+++ b/test/src/sys/sendfile/sendfile_test.cpp
@@ -35,7 +35,7 @@ TEST(LlvmLibcSendfileTest, CreateAndTransfer) {
constexpr const char *OUT_FILE = "testdata/sendfile_out.test";
const char IN_DATA[] = "sendfile test";
constexpr ssize_t IN_SIZE = ssize_t(sizeof(IN_DATA));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int in_fd = LIBC_NAMESPACE::open(IN_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(in_fd, 0);
diff --git a/test/src/sys/socket/linux/bind_test.cpp b/test/src/sys/socket/linux/bind_test.cpp
index 305e4889f394..e70cbd578290 100644
--- a/test/src/sys/socket/linux/bind_test.cpp
+++ b/test/src/sys/socket/linux/bind_test.cpp
@@ -13,7 +13,6 @@
#include "src/unistd/close.h"
#include "src/errno/libc_errno.h"
-#include "test/UnitTest/LibcTest.h"
#include "test/UnitTest/Test.h"
#include <sys/socket.h> // For AF_UNIX and SOCK_DGRAM
diff --git a/test/src/sys/stat/chmod_test.cpp b/test/src/sys/stat/chmod_test.cpp
index 6fd056b2bd6c..c688996615ce 100644
--- a/test/src/sys/stat/chmod_test.cpp
+++ b/test/src/sys/stat/chmod_test.cpp
@@ -28,7 +28,7 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
constexpr const char *TEST_FILE = "testdata/chmod.test";
const char WRITE_DATA[] = "test data";
constexpr ssize_t WRITE_SIZE = ssize_t(sizeof(WRITE_DATA));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_WRONLY);
ASSERT_GT(fd, 0);
@@ -46,7 +46,7 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
// Opening for writing should fail.
EXPECT_EQ(LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_WRONLY), -1);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// But opening for reading should succeed.
fd = LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_RDONLY);
EXPECT_GT(fd, 0);
@@ -57,9 +57,9 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
}
TEST(LlvmLibcChmodTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
ASSERT_THAT(LIBC_NAMESPACE::chmod("non-existent-file", S_IRUSR),
Fails(ENOENT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/stat/fchmod_test.cpp b/test/src/sys/stat/fchmod_test.cpp
index a0a93b03d22e..91c0f68b8708 100644
--- a/test/src/sys/stat/fchmod_test.cpp
+++ b/test/src/sys/stat/fchmod_test.cpp
@@ -28,7 +28,7 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
constexpr const char *TEST_FILE = "testdata/fchmod.test";
const char WRITE_DATA[] = "test data";
constexpr ssize_t WRITE_SIZE = ssize_t(sizeof(WRITE_DATA));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_WRONLY);
ASSERT_GT(fd, 0);
@@ -46,7 +46,7 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
// Opening for writing should fail.
EXPECT_EQ(LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_WRONLY), -1);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// But opening for reading should succeed.
fd = LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_RDONLY);
EXPECT_GT(fd, 0);
@@ -57,8 +57,8 @@ TEST(LlvmLibcChmodTest, ChangeAndOpen) {
}
TEST(LlvmLibcChmodTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::fchmod(-1, S_IRUSR), -1);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/stat/fchmodat_test.cpp b/test/src/sys/stat/fchmodat_test.cpp
index e2cf170728ec..c43ef8ae1331 100644
--- a/test/src/sys/stat/fchmodat_test.cpp
+++ b/test/src/sys/stat/fchmodat_test.cpp
@@ -30,7 +30,7 @@ TEST(LlvmLibcFchmodatTest, ChangeAndOpen) {
constexpr const char *TEST_FILE_BASENAME = "fchmodat.test";
const char WRITE_DATA[] = "fchmodat test";
constexpr ssize_t WRITE_SIZE = ssize_t(sizeof(WRITE_DATA));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
@@ -49,7 +49,7 @@ TEST(LlvmLibcFchmodatTest, ChangeAndOpen) {
// Opening for writing should fail.
EXPECT_EQ(LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_WRONLY), -1);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
// But opening for reading should succeed.
fd = LIBC_NAMESPACE::open(TEST_FILE, O_APPEND | O_RDONLY);
EXPECT_GT(fd, 0);
@@ -63,10 +63,10 @@ TEST(LlvmLibcFchmodatTest, ChangeAndOpen) {
}
TEST(LlvmLibcFchmodatTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
ASSERT_THAT(
LIBC_NAMESPACE::fchmodat(AT_FDCWD, "non-existent-file", S_IRUSR, 0),
Fails(ENOENT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/stat/fstat_test.cpp b/test/src/sys/stat/fstat_test.cpp
index 33769ea1f05a..1379eae26a47 100644
--- a/test/src/sys/stat/fstat_test.cpp
+++ b/test/src/sys/stat/fstat_test.cpp
@@ -26,7 +26,7 @@ TEST(LlvmLibcFStatTest, CreatAndReadMode) {
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/fstat.test";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
@@ -42,9 +42,9 @@ TEST(LlvmLibcFStatTest, CreatAndReadMode) {
}
TEST(LlvmLibcFStatTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(LIBC_NAMESPACE::fstat(-1, &statbuf), Fails(EBADF));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/stat/lstat_test.cpp b/test/src/sys/stat/lstat_test.cpp
index a3b3c2cb0c1d..b44b3d1a59ce 100644
--- a/test/src/sys/stat/lstat_test.cpp
+++ b/test/src/sys/stat/lstat_test.cpp
@@ -26,7 +26,7 @@ TEST(LlvmLibcLStatTest, CreatAndReadMode) {
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/lstat.test";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
@@ -42,10 +42,10 @@ TEST(LlvmLibcLStatTest, CreatAndReadMode) {
}
TEST(LlvmLibcLStatTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(LIBC_NAMESPACE::lstat("non-existent-file", &statbuf),
Fails(ENOENT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/stat/mkdirat_test.cpp b/test/src/sys/stat/mkdirat_test.cpp
index ae11af4f6b9b..cbacc16b402d 100644
--- a/test/src/sys/stat/mkdirat_test.cpp
+++ b/test/src/sys/stat/mkdirat_test.cpp
@@ -15,7 +15,8 @@
TEST(LlvmLibcMkdiratTest, CreateAndRemove) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata/mkdirat.testdir";
+ constexpr const char *FILENAME = "testdata/mkdirat.testdir";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
Succeeds(0));
ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));
diff --git a/test/src/sys/stat/stat_test.cpp b/test/src/sys/stat/stat_test.cpp
index 1286e12fd611..baf363382022 100644
--- a/test/src/sys/stat/stat_test.cpp
+++ b/test/src/sys/stat/stat_test.cpp
@@ -26,7 +26,7 @@ TEST(LlvmLibcStatTest, CreatAndReadMode) {
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/stat.test";
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
@@ -42,10 +42,10 @@ TEST(LlvmLibcStatTest, CreatAndReadMode) {
}
TEST(LlvmLibcStatTest, NonExistentFile) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(LIBC_NAMESPACE::stat("non-existent-file", &statbuf),
Fails(ENOENT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/sys/statvfs/linux/fstatvfs_test.cpp b/test/src/sys/statvfs/linux/fstatvfs_test.cpp
new file mode 100644
index 000000000000..bd5195c7969b
--- /dev/null
+++ b/test/src/sys/statvfs/linux/fstatvfs_test.cpp
@@ -0,0 +1,42 @@
+#include "llvm-libc-macros/linux/fcntl-macros.h"
+#include "src/fcntl/open.h"
+#include "src/sys/statvfs/fstatvfs.h"
+#include "src/sys/statvfs/linux/statfs_utils.h"
+#include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include <linux/magic.h>
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+namespace LIBC_NAMESPACE {
+static int fstatfs(int fd, struct statfs *buf) {
+ using namespace statfs_utils;
+ if (cpp::optional<LinuxStatFs> result = linux_fstatfs(fd)) {
+ *buf = *result;
+ return 0;
+ }
+ return -1;
+}
+} // namespace LIBC_NAMESPACE
+
+struct PathFD {
+ int fd;
+ explicit PathFD(const char *path)
+ : fd(LIBC_NAMESPACE::open(path, O_CLOEXEC | O_PATH)) {}
+ ~PathFD() { LIBC_NAMESPACE::close(fd); }
+ operator int() const { return fd; }
+};
+
+TEST(LlvmLibcSysStatvfsTest, FstatfsBasic) {
+ struct statfs buf;
+ ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/"), &buf), Succeeds());
+ ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/proc"), &buf), Succeeds());
+ ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(PROC_SUPER_MAGIC));
+ ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/sys"), &buf), Succeeds());
+ ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(SYSFS_MAGIC));
+}
+
+TEST(LlvmLibcSysStatvfsTest, FstatvfsInvalidFD) {
+ struct statvfs buf;
+ ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(-1, &buf), Fails(EBADF));
+}
diff --git a/test/src/sys/statvfs/linux/statvfs_test.cpp b/test/src/sys/statvfs/linux/statvfs_test.cpp
new file mode 100644
index 000000000000..695d2c0d5e98
--- /dev/null
+++ b/test/src/sys/statvfs/linux/statvfs_test.cpp
@@ -0,0 +1,47 @@
+#include "src/sys/statvfs/linux/statfs_utils.h"
+#include "src/sys/statvfs/statvfs.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include <linux/magic.h>
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+namespace LIBC_NAMESPACE {
+static int statfs(const char *path, struct statfs *buf) {
+ using namespace statfs_utils;
+ if (cpp::optional<LinuxStatFs> result = linux_statfs(path)) {
+ *buf = *result;
+ return 0;
+ }
+ return -1;
+}
+} // namespace LIBC_NAMESPACE
+
+TEST(LlvmLibcSysStatfsTest, StatfsBasic) {
+ struct statfs buf;
+ ASSERT_THAT(LIBC_NAMESPACE::statfs("/", &buf), Succeeds());
+ ASSERT_THAT(LIBC_NAMESPACE::statfs("/proc", &buf), Succeeds());
+ ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(PROC_SUPER_MAGIC));
+ ASSERT_THAT(LIBC_NAMESPACE::statfs("/sys", &buf), Succeeds());
+ ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(SYSFS_MAGIC));
+}
+
+TEST(LlvmLibcSysStatfsTest, StatvfsInvalidPath) {
+ struct statvfs buf;
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs("", &buf), Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs("/nonexistent", &buf), Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs("/dev/null/whatever", &buf),
+ Fails(ENOTDIR));
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs(nullptr, &buf), Fails(EFAULT));
+}
+
+TEST(LlvmLibcSysStatfsTest, StatvfsNameTooLong) {
+ struct statvfs buf;
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs("/", &buf), Succeeds());
+ char *name = static_cast<char *>(__builtin_alloca(buf.f_namemax + 3));
+ name[0] = '/';
+ name[buf.f_namemax + 2] = '\0';
+ for (unsigned i = 1; i < buf.f_namemax + 2; ++i) {
+ name[i] = 'a';
+ }
+ ASSERT_THAT(LIBC_NAMESPACE::statvfs(name, &buf), Fails(ENAMETOOLONG));
+}
diff --git a/test/src/termios/termios_test.cpp b/test/src/termios/termios_test.cpp
index 790c010c5b7e..f8fc09a8bbf0 100644
--- a/test/src/termios/termios_test.cpp
+++ b/test/src/termios/termios_test.cpp
@@ -30,21 +30,21 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcTermiosTest, SpeedSmokeTest) {
struct termios t;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, B50), Succeeds(0));
ASSERT_EQ(LIBC_NAMESPACE::cfgetispeed(&t), speed_t(B50));
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, B75), Succeeds(0));
ASSERT_EQ(LIBC_NAMESPACE::cfgetospeed(&t), speed_t(B75));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, ~CBAUD), Fails(EINVAL));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, ~CBAUD), Fails(EINVAL));
}
TEST(LlvmLibcTermiosTest, GetAttrSmokeTest) {
struct termios t;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open("/dev/tty", O_RDONLY);
if (fd < 0)
return; // When /dev/tty is not available, no point continuing.
@@ -54,7 +54,7 @@ TEST(LlvmLibcTermiosTest, GetAttrSmokeTest) {
}
TEST(LlvmLibcTermiosTest, TcGetSidSmokeTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open("/dev/tty", O_RDONLY);
if (fd < 0)
return; // When /dev/tty is not available, no point continuing.
diff --git a/test/src/time/TmHelper.h b/test/src/time/TmHelper.h
index d8e638d8dbaf..16210944bf15 100644
--- a/test/src/time/TmHelper.h
+++ b/test/src/time/TmHelper.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
-#define LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
+#ifndef LLVM_LIBC_TEST_SRC_TIME_TMHELPER_H
+#define LLVM_LIBC_TEST_SRC_TIME_TMHELPER_H
#include <time.h>
@@ -40,4 +40,4 @@ static inline void initialize_tm_data(struct tm *tm_data, int year, int month,
} // namespace tmhelper
} // namespace LIBC_NAMESPACE
-#endif // LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
+#endif // LLVM_LIBC_TEST_SRC_TIME_TMHELPER_H
diff --git a/test/src/time/asctime_r_test.cpp b/test/src/time/asctime_r_test.cpp
index 1abaa135350c..f3aadbb39de4 100644
--- a/test/src/time/asctime_r_test.cpp
+++ b/test/src/time/asctime_r_test.cpp
@@ -27,17 +27,17 @@ static inline char *call_asctime_r(struct tm *tm_data, int year, int month,
TEST(LlvmLibcAsctimeR, Nullptr) {
char *result;
result = LIBC_NAMESPACE::asctime_r(nullptr, nullptr);
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
result = LIBC_NAMESPACE::asctime_r(nullptr, buffer);
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
struct tm tm_data;
result = LIBC_NAMESPACE::asctime_r(&tm_data, nullptr);
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
}
diff --git a/test/src/time/asctime_test.cpp b/test/src/time/asctime_test.cpp
index 4b5ceb596aa4..169a7463a303 100644
--- a/test/src/time/asctime_test.cpp
+++ b/test/src/time/asctime_test.cpp
@@ -22,7 +22,7 @@ static inline char *call_asctime(struct tm *tm_data, int year, int month,
TEST(LlvmLibcAsctime, Nullptr) {
char *result;
result = LIBC_NAMESPACE::asctime(nullptr);
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
}
@@ -40,7 +40,7 @@ TEST(LlvmLibcAsctime, InvalidWday) {
0, // sec
-1, // wday
0); // yday
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
// Test with wday = 7.
call_asctime(&tm_data,
@@ -52,7 +52,7 @@ TEST(LlvmLibcAsctime, InvalidWday) {
0, // sec
7, // wday
0); // yday
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
}
// Months are from January to December. Test passing invalid value in month.
@@ -69,7 +69,7 @@ TEST(LlvmLibcAsctime, InvalidMonth) {
0, // sec
4, // wday
0); // yday
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
// Test with month = 13.
call_asctime(&tm_data,
@@ -81,7 +81,7 @@ TEST(LlvmLibcAsctime, InvalidMonth) {
0, // sec
4, // wday
0); // yday
- ASSERT_EQ(EINVAL, libc_errno);
+ ASSERT_ERRNO_EQ(EINVAL);
}
TEST(LlvmLibcAsctime, ValidWeekdays) {
@@ -209,6 +209,6 @@ TEST(LlvmLibcAsctime, Max64BitYear) {
50, // sec
2, // wday
50); // yday
- ASSERT_EQ(EOVERFLOW, libc_errno);
+ ASSERT_ERRNO_EQ(EOVERFLOW);
ASSERT_STREQ(nullptr, result);
}
diff --git a/test/src/time/gmtime_test.cpp b/test/src/time/gmtime_test.cpp
index d4bcc7d5831e..433fbf666705 100644
--- a/test/src/time/gmtime_test.cpp
+++ b/test/src/time/gmtime_test.cpp
@@ -28,7 +28,7 @@ TEST(LlvmLibcGmTime, OutOfRange) {
EXPECT_TRUE(tm_data == nullptr);
ASSERT_ERRNO_EQ(EOVERFLOW);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
seconds = INT_MIN * static_cast<int64_t>(
TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR) -
1;
diff --git a/test/src/time/nanosleep_test.cpp b/test/src/time/nanosleep_test.cpp
index 8baaa29df478..2a6eea4d5e16 100644
--- a/test/src/time/nanosleep_test.cpp
+++ b/test/src/time/nanosleep_test.cpp
@@ -18,7 +18,7 @@ namespace cpp = LIBC_NAMESPACE::cpp;
TEST(LlvmLibcNanosleep, SmokeTest) {
// TODO: When we have the code to read clocks, test that time has passed.
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
struct timespec tim = {1, 500};
struct timespec tim2 = {0, 0};
diff --git a/test/src/unistd/_exit_test.cpp b/test/src/unistd/_exit_test.cpp
new file mode 100644
index 000000000000..6d0e4465dbba
--- /dev/null
+++ b/test/src/unistd/_exit_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for _exit -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/unistd/_exit.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcUniStd, _exit) {
+ EXPECT_EXITS([] { LIBC_NAMESPACE::_exit(1); }, 1);
+ EXPECT_EXITS([] { LIBC_NAMESPACE::_exit(65); }, 65);
+}
diff --git a/test/src/unistd/access_test.cpp b/test/src/unistd/access_test.cpp
index 671800584602..808cd5f3c8d8 100644
--- a/test/src/unistd/access_test.cpp
+++ b/test/src/unistd/access_test.cpp
@@ -12,6 +12,7 @@
#include "src/unistd/close.h"
#include "src/unistd/unlink.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
#include "test/UnitTest/Test.h"
#include <sys/stat.h>
@@ -20,9 +21,10 @@
TEST(LlvmLibcAccessTest, CreateAndTest) {
// The test strategy is to repeatedly create a file in different modes and
// test that it is accessable in those modes but not in others.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/access.test";
+ constexpr const char *FILENAME = "access.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
@@ -44,10 +46,10 @@ TEST(LlvmLibcAccessTest, CreateAndTest) {
ASSERT_ERRNO_SUCCESS();
ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, R_OK), -1);
ASSERT_ERRNO_EQ(EACCES);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::access(TEST_FILE, W_OK), -1);
ASSERT_ERRNO_EQ(EACCES);
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
}
diff --git a/test/src/unistd/chdir_test.cpp b/test/src/unistd/chdir_test.cpp
index 6676b71eed73..51dc7bb15d3e 100644
--- a/test/src/unistd/chdir_test.cpp
+++ b/test/src/unistd/chdir_test.cpp
@@ -21,10 +21,13 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
// directory and open the same file to make sure that the "chdir" operation
// succeeded.
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata";
- constexpr const char *TEST_FILE = "testdata/chdir.test";
- constexpr const char *TEST_FILE_BASE = "chdir.test";
- libc_errno = 0;
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "testdata/chdir.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
+ constexpr const char *FILENAME3 = "chdir.test";
+ auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_PATH);
ASSERT_GT(fd, 0);
@@ -39,8 +42,8 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
}
TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
ASSERT_THAT(LIBC_NAMESPACE::chdir("non-existent-dir"), Fails(ENOENT));
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/unistd/dup2_test.cpp b/test/src/unistd/dup2_test.cpp
index 70ea1a72bc8e..2b2b3f3eef9a 100644
--- a/test/src/unistd/dup2_test.cpp
+++ b/test/src/unistd/dup2_test.cpp
@@ -20,9 +20,10 @@
TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
constexpr int DUPFD = 0xD0;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/dup2.test";
+ constexpr const char *FILENAME = "dup2.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/dup3_test.cpp b/test/src/unistd/dup3_test.cpp
index 9c13de47f0be..7b1c8e0e2519 100644
--- a/test/src/unistd/dup3_test.cpp
+++ b/test/src/unistd/dup3_test.cpp
@@ -25,10 +25,11 @@
TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
constexpr int DUPFD = 0xD0;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/dup3.test";
+ constexpr const char *FILENAME = "dup3.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/dup_test.cpp b/test/src/unistd/dup_test.cpp
index 23abf5969fc2..c7bf87714210 100644
--- a/test/src/unistd/dup_test.cpp
+++ b/test/src/unistd/dup_test.cpp
@@ -19,9 +19,10 @@
#include <sys/stat.h>
TEST(LlvmLibcdupTest, ReadAndWriteViaDup) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/dup.test";
+ constexpr const char *FILENAME = "dup.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/fchdir_test.cpp b/test/src/unistd/fchdir_test.cpp
index 0d870e35f51c..ae88e1f22ed6 100644
--- a/test/src/unistd/fchdir_test.cpp
+++ b/test/src/unistd/fchdir_test.cpp
@@ -21,10 +21,13 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
// directory and open the same file to make sure that the "fchdir" operation
// succeeded.
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata";
- constexpr const char *TEST_FILE = "testdata/fchdir.test";
- constexpr const char *TEST_FILE_BASE = "fchdir.test";
- libc_errno = 0;
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "testdata/fchdir.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
+ constexpr const char *FILENAME3 = "fchdir.test";
+ auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME3);
+ LIBC_NAMESPACE::libc_errno = 0;
int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
ASSERT_GT(dir_fd, 0);
@@ -44,8 +47,8 @@ TEST(LlvmLibcChdirTest, ChangeAndOpen) {
TEST(LlvmLibcChdirTest, ChangeToNonExistentDir) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_EQ(LIBC_NAMESPACE::fchdir(0), -1);
ASSERT_ERRNO_FAILURE();
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
}
diff --git a/test/src/unistd/ftruncate_test.cpp b/test/src/unistd/ftruncate_test.cpp
index 50a3508e0a87..2fe4002692a8 100644
--- a/test/src/unistd/ftruncate_test.cpp
+++ b/test/src/unistd/ftruncate_test.cpp
@@ -23,7 +23,8 @@ namespace cpp = LIBC_NAMESPACE::cpp;
TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char TEST_FILE[] = "testdata/ftruncate.test";
+ constexpr const char *FILENAME = "ftruncate.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
constexpr const char WRITE_DATA[] = "hello, ftruncate";
constexpr size_t WRITE_SIZE = sizeof(WRITE_DATA);
char buf[WRITE_SIZE];
@@ -33,7 +34,7 @@ TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
// 2. Read it to make sure what was written is actually in the file.
// 3. Truncate to 1 byte.
// 4. Try to read more than 1 byte and fail.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
@@ -68,5 +69,5 @@ TEST(LlvmLibcFtruncateTest, CreateAndTruncate) {
TEST(LlvmLibcFtruncateTest, TruncateBadFD) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- ASSERT_THAT(LIBC_NAMESPACE::ftruncate(1, off_t(1)), Fails(EINVAL));
+ ASSERT_THAT(LIBC_NAMESPACE::ftruncate(0, off_t(1)), Fails(EINVAL));
}
diff --git a/test/src/unistd/isatty_test.cpp b/test/src/unistd/isatty_test.cpp
index c0e14c344b43..c20eead46c06 100644
--- a/test/src/unistd/isatty_test.cpp
+++ b/test/src/unistd/isatty_test.cpp
@@ -21,7 +21,7 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
TEST(LlvmLibcIsATTYTest, StdInOutTests) {
// If stdin is connected to a terminal, assume that all of the standard i/o
// fds are.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
if (LIBC_NAMESPACE::isatty(0)) {
EXPECT_THAT(LIBC_NAMESPACE::isatty(0), Succeeds(1)); // stdin
EXPECT_THAT(LIBC_NAMESPACE::isatty(1), Succeeds(1)); // stdout
@@ -34,13 +34,14 @@ TEST(LlvmLibcIsATTYTest, StdInOutTests) {
}
TEST(LlvmLibcIsATTYTest, BadFdTest) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
EXPECT_THAT(LIBC_NAMESPACE::isatty(-1), Fails(EBADF, 0)); // invalid fd
}
TEST(LlvmLibcIsATTYTest, DevTTYTest) {
- constexpr const char *TTY_FILE = "/dev/tty";
- libc_errno = 0;
+ constexpr const char *FILENAME = "/dev/tty";
+ auto TTY_FILE = libc_make_test_file_path(FILENAME);
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TTY_FILE, O_RDONLY);
if (fd > 0) {
ASSERT_ERRNO_SUCCESS();
@@ -50,8 +51,9 @@ TEST(LlvmLibcIsATTYTest, DevTTYTest) {
}
TEST(LlvmLibcIsATTYTest, FileTest) {
- constexpr const char *TEST_FILE = "testdata/isatty.test";
- libc_errno = 0;
+ constexpr const char *FILENAME = "isatty.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/link_test.cpp b/test/src/unistd/link_test.cpp
index bf6962b397b2..3f1af2ec63f5 100644
--- a/test/src/unistd/link_test.cpp
+++ b/test/src/unistd/link_test.cpp
@@ -18,15 +18,17 @@
TEST(LlvmLibcLinkTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/link.test";
- constexpr const char *TEST_FILE_LINK = "testdata/link.test.link";
+ constexpr const char *FILENAME = "link.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "link.test.link";
+ auto TEST_FILE_LINK = libc_make_test_file_path(FILENAME2);
// The test strategy is as follows:
// 1. Create a normal file
// 2. Create a link to that file.
// 3. Open the link to check that the link was created.
// 4. Cleanup the file and its link.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(write_fd, 0);
@@ -44,7 +46,6 @@ TEST(LlvmLibcLinkTest, CreateAndUnlink) {
TEST(LlvmLibcLinkTest, LinkToNonExistentFile) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- ASSERT_THAT(
- LIBC_NAMESPACE::link("testdata/non-existent-file", "testdata/bad-link"),
- Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::link("non-existent-file", "bad-link"),
+ Fails(ENOENT));
}
diff --git a/test/src/unistd/linkat_test.cpp b/test/src/unistd/linkat_test.cpp
index 62fbaacac08e..c6e457560428 100644
--- a/test/src/unistd/linkat_test.cpp
+++ b/test/src/unistd/linkat_test.cpp
@@ -18,18 +18,23 @@
TEST(LlvmLibcLinkatTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata";
- constexpr const char *TEST_FILE = "linkat.test";
- constexpr const char *TEST_FILE_PATH = "testdata/linkat.test";
- constexpr const char *TEST_FILE_LINK = "linkat.test.link";
- constexpr const char *TEST_FILE_LINK_PATH = "testdata/linkat.test.link";
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "linkat.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
+ constexpr const char *FILENAME3 = "testdata/linkat.test";
+ auto TEST_FILE_PATH = libc_make_test_file_path(FILENAME3);
+ constexpr const char *FILENAME4 = "linkat.test.link";
+ auto TEST_FILE_LINK = libc_make_test_file_path(FILENAME4);
+ constexpr const char *FILENAME5 = "testdata/linkat.test.link";
+ auto TEST_FILE_LINK_PATH = libc_make_test_file_path(FILENAME5);
// The test strategy is as follows:
// 1. Create a normal file
// 2. Create a link to that file.
// 3. Open the link to check that the link was created.
// 4. Cleanup the file and its link.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int write_fd =
LIBC_NAMESPACE::open(TEST_FILE_PATH, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
diff --git a/test/src/unistd/lseek_test.cpp b/test/src/unistd/lseek_test.cpp
index fd73bccf0cb8..40c0bf07df31 100644
--- a/test/src/unistd/lseek_test.cpp
+++ b/test/src/unistd/lseek_test.cpp
@@ -18,7 +18,8 @@
TEST(LlvmLibcUniStd, LseekTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/lseek.test";
+ constexpr const char *FILENAME = "testdata/lseek.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
@@ -52,7 +53,8 @@ TEST(LlvmLibcUniStd, LseekTest) {
TEST(LlvmLibcUniStd, LseekFailsTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/lseek.test";
+ constexpr const char *FILENAME = "testdata/lseek.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/pread_pwrite_test.cpp b/test/src/unistd/pread_pwrite_test.cpp
index 1d17778e550f..3c42fcc777a6 100644
--- a/test/src/unistd/pread_pwrite_test.cpp
+++ b/test/src/unistd/pread_pwrite_test.cpp
@@ -32,7 +32,8 @@ TEST(LlvmLibcUniStd, PWriteAndPReadBackTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/pread_pwrite.test";
+ constexpr const char *FILENAME = "pread_pwrite.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/read_write_test.cpp b/test/src/unistd/read_write_test.cpp
index 133057358220..8b6ba427a343 100644
--- a/test/src/unistd/read_write_test.cpp
+++ b/test/src/unistd/read_write_test.cpp
@@ -8,6 +8,7 @@
#include "src/errno/libc_errno.h"
#include "src/fcntl/open.h"
+#include "src/stdio/remove.h"
#include "src/unistd/close.h"
#include "src/unistd/fsync.h"
#include "src/unistd/read.h"
@@ -19,7 +20,9 @@
TEST(LlvmLibcUniStd, WriteAndReadBackTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "__unistd_read_write.test";
+ constexpr const char *FILENAME = "__unistd_read_write.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
+
int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(write_fd, 0);
@@ -39,7 +42,7 @@ TEST(LlvmLibcUniStd, WriteAndReadBackTest) {
EXPECT_STREQ(read_buf, HELLO);
ASSERT_THAT(LIBC_NAMESPACE::close(read_fd), Succeeds(0));
- // TODO: 'remove' the test file after the test.
+ ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
}
TEST(LlvmLibcUniStd, WriteFails) {
diff --git a/test/src/unistd/readlink_test.cpp b/test/src/unistd/readlink_test.cpp
index 19b339ec2b37..20f395134911 100644
--- a/test/src/unistd/readlink_test.cpp
+++ b/test/src/unistd/readlink_test.cpp
@@ -18,9 +18,11 @@ namespace cpp = LIBC_NAMESPACE::cpp;
TEST(LlvmLibcReadlinkTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char LINK_VAL[] = "readlink_test_value";
- constexpr const char LINK[] = "testdata/readlink.test.link";
- libc_errno = 0;
+ constexpr const char *FILENAME = "readlink_test_value";
+ auto LINK_VAL = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "readlink.test.link";
+ auto LINK = libc_make_test_file_path(FILENAME2);
+ LIBC_NAMESPACE::libc_errno = 0;
// The test strategy is as follows:
// 1. Create a symlink with value LINK_VAL.
diff --git a/test/src/unistd/readlinkat_test.cpp b/test/src/unistd/readlinkat_test.cpp
index 85cbca084778..39d81d9ba544 100644
--- a/test/src/unistd/readlinkat_test.cpp
+++ b/test/src/unistd/readlinkat_test.cpp
@@ -20,9 +20,11 @@ namespace cpp = LIBC_NAMESPACE::cpp;
TEST(LlvmLibcReadlinkatTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char LINK_VAL[] = "readlinkat_test_value";
- constexpr const char LINK[] = "testdata/readlinkat.test.link";
- libc_errno = 0;
+ constexpr const char *FILENAME = "readlinkat_test_value";
+ auto LINK_VAL = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "readlinkat.test.link";
+ auto LINK = libc_make_test_file_path(FILENAME2);
+ LIBC_NAMESPACE::libc_errno = 0;
// The test strategy is as follows:
// 1. Create a symlink with value LINK_VAL.
diff --git a/test/src/unistd/rmdir_test.cpp b/test/src/unistd/rmdir_test.cpp
index 69228ce98c82..93cb0f3f53c1 100644
--- a/test/src/unistd/rmdir_test.cpp
+++ b/test/src/unistd/rmdir_test.cpp
@@ -16,13 +16,13 @@
TEST(LlvmLibcRmdirTest, CreateAndRemove) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata/rmdir.testdir";
+ constexpr const char *FILENAME = "rmdir.testdir";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
ASSERT_THAT(LIBC_NAMESPACE::mkdir(TEST_DIR, S_IRWXU), Succeeds(0));
ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));
}
TEST(LlvmLibcRmdirTest, RemoveNonExistentDir) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- ASSERT_THAT(LIBC_NAMESPACE::rmdir("testdata/non-existent-dir"),
- Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::rmdir("non-existent-dir"), Fails(ENOENT));
}
diff --git a/test/src/unistd/symlink_test.cpp b/test/src/unistd/symlink_test.cpp
index e0c5979a6087..9e8b81c38269 100644
--- a/test/src/unistd/symlink_test.cpp
+++ b/test/src/unistd/symlink_test.cpp
@@ -18,16 +18,19 @@
TEST(LlvmLibcSymlinkTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE_BASE = "symlink.test";
- constexpr const char *TEST_FILE = "testdata/symlink.test";
- constexpr const char *TEST_FILE_LINK = "testdata/symlink.test.symlink";
+ constexpr const char *FILENAME = "symlink.test";
+ auto TEST_FILE_BASE = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "symlink.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
+ constexpr const char *FILENAME3 = "symlink.test.symlink";
+ auto TEST_FILE_LINK = libc_make_test_file_path(FILENAME3);
// The test strategy is as follows:
// 1. Create a normal file
// 2. Create a symlink to that file.
// 3. Open the symlink to check that the symlink was created.
// 4. Cleanup the file and its symlink.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(write_fd, 0);
diff --git a/test/src/unistd/symlinkat_test.cpp b/test/src/unistd/symlinkat_test.cpp
index 1ab4dc8417d6..b6588a988b79 100644
--- a/test/src/unistd/symlinkat_test.cpp
+++ b/test/src/unistd/symlinkat_test.cpp
@@ -18,18 +18,23 @@
TEST(LlvmLibcSymlinkatTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata";
- constexpr const char *TEST_FILE = "symlinkat.test";
- constexpr const char *TEST_FILE_PATH = "testdata/symlinkat.test";
- constexpr const char *TEST_FILE_LINK = "symlinkat.test.link";
- constexpr const char *TEST_FILE_LINK_PATH = "testdata/symlinkat.test.link";
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "symlinkat.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
+ constexpr const char *FILENAME3 = "testdata/symlinkat.test";
+ auto TEST_FILE_PATH = libc_make_test_file_path(FILENAME3);
+ constexpr const char *FILENAME4 = "symlinkat.test.link";
+ auto TEST_FILE_LINK = libc_make_test_file_path(FILENAME4);
+ constexpr const char *FILENAME5 = "testdata/symlinkat.test.link";
+ auto TEST_FILE_LINK_PATH = libc_make_test_file_path(FILENAME5);
// The test strategy is as follows:
// 1. Create a normal file
// 2. Create a link to that file.
// 3. Open the link to check that the link was created.
// 4. Cleanup the file and its link.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int write_fd =
LIBC_NAMESPACE::open(TEST_FILE_PATH, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
diff --git a/test/src/unistd/syscall_test.cpp b/test/src/unistd/syscall_test.cpp
index aabbffc20d1b..cee29bd9afa3 100644
--- a/test/src/unistd/syscall_test.cpp
+++ b/test/src/unistd/syscall_test.cpp
@@ -27,7 +27,7 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
// because the macro generates a call to the actual internal function
// (__llvm_libc_syscall) which is inside the namespace.
TEST(LlvmLibcSyscallTest, TrivialCall) {
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l);
ASSERT_ERRNO_SUCCESS();
diff --git a/test/src/unistd/truncate_test.cpp b/test/src/unistd/truncate_test.cpp
index 4d316ed1b16f..261dd63d2afc 100644
--- a/test/src/unistd/truncate_test.cpp
+++ b/test/src/unistd/truncate_test.cpp
@@ -23,7 +23,8 @@ namespace cpp = LIBC_NAMESPACE::cpp;
TEST(LlvmLibcTruncateTest, CreateAndTruncate) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char TEST_FILE[] = "testdata/truncate.test";
+ constexpr const char *FILENAME = "truncate.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
constexpr const char WRITE_DATA[] = "hello, truncate";
constexpr size_t WRITE_SIZE = sizeof(WRITE_DATA);
char buf[WRITE_SIZE];
@@ -33,7 +34,7 @@ TEST(LlvmLibcTruncateTest, CreateAndTruncate) {
// 2. Read it to make sure what was written is actually in the file.
// 3. Truncate to 1 byte.
// 4. Try to read more than 1 byte and fail.
- libc_errno = 0;
+ LIBC_NAMESPACE::libc_errno = 0;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);
diff --git a/test/src/unistd/unlink_test.cpp b/test/src/unistd/unlink_test.cpp
index c2828df65a18..e1ffaab78147 100644
--- a/test/src/unistd/unlink_test.cpp
+++ b/test/src/unistd/unlink_test.cpp
@@ -17,7 +17,8 @@
TEST(LlvmLibcUnlinkTest, CreateAndUnlink) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE = "testdata/unlink.test";
+ constexpr const char *FILENAME = "unlink.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME);
int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(write_fd, 0);
@@ -27,6 +28,5 @@ TEST(LlvmLibcUnlinkTest, CreateAndUnlink) {
TEST(LlvmLibcUnlinkTest, UnlinkNonExistentFile) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- ASSERT_THAT(LIBC_NAMESPACE::unlink("testdata/non-existent-file"),
- Fails(ENOENT));
+ ASSERT_THAT(LIBC_NAMESPACE::unlink("non-existent-file"), Fails(ENOENT));
}
diff --git a/test/src/unistd/unlinkat_test.cpp b/test/src/unistd/unlinkat_test.cpp
index ac32ed4895d6..2d64a996e644 100644
--- a/test/src/unistd/unlinkat_test.cpp
+++ b/test/src/unistd/unlinkat_test.cpp
@@ -18,8 +18,10 @@
TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_DIR = "testdata";
- constexpr const char *TEST_FILE = "openat.test";
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
+ constexpr const char *FILENAME2 = "openat.test";
+ auto TEST_FILE = libc_make_test_file_path(FILENAME2);
int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(dir_fd, 0);
@@ -33,7 +35,8 @@ TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
}
TEST(LlvmLibcUnlinkatTest, UnlinkatNonExistentFile) {
- constexpr const char *TEST_DIR = "testdata";
+ constexpr const char *FILENAME = "testdata";
+ auto TEST_DIR = libc_make_test_file_path(FILENAME);
int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(dir_fd, 0);
diff --git a/test/utils/FPUtil/x86_long_double_test.cpp b/test/utils/FPUtil/x86_long_double_test.cpp
index bafbbe2a4107..3b140c6c0266 100644
--- a/test/utils/FPUtil/x86_long_double_test.cpp
+++ b/test/utils/FPUtil/x86_long_double_test.cpp
@@ -9,7 +9,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
using FPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;