diff options
author | LLVM libc <llvm-libc@google.com> | 2024-04-05 18:06:12 +0530 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-04-05 11:04:00 -0700 |
commit | afe527ab9651fa77716706a96ddba233e078de55 (patch) | |
tree | 16cbe89196213c974abe1af0fb7f0559ccce36e8 | |
parent | 52153e27ed3cac945247e6b1eeba1385efb78f6f (diff) | |
download | llvm-libc-afe527ab9651fa77716706a96ddba233e078de55.tar.gz |
Project import generated by Copybara.
GitOrigin-RevId: 3b961d113e6986eb9a6b448b72a730c289b8e6ab
Change-Id: I9b459fafe52e3f2f19dc1ae4b306f3d7dc6178f9
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 ÷r) { + 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 ÷nd, + const BigInt ÷r) { + 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 ÷nd, + const BigInt ÷r) { + // 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 §ion) { + 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, ¶m), -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, ¶m), -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, ¶m), -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, ¶m), -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, ¶m), 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, ¶m), -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, ¶m), -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, ¶m), 0); @@ -113,17 +115,18 @@ public: // Negative pid ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(-1, ¶m), -1); ASSERT_ERRNO_EQ(EINVAL); - libc_errno = 0; + LIBC_NAMESPACE::libc_errno = 0; ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(-1, ¶m), -1); ASSERT_ERRNO_EQ(EINVAL); - libc_errno = 0; + LIBC_NAMESPACE::libc_errno = 0; // Success / missing permissions ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, ¶m), 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, ¶m), 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>; |