diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index c2179938b40d1..b949e4b4f67ba 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -370,6 +370,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.conj libc.src.complex.conjf libc.src.complex.conjl + libc.src.complex.cproj + libc.src.complex.cprojf + libc.src.complex.cprojl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -622,6 +625,7 @@ if(LIBC_TYPES_HAS_FLOAT16) # libc.src.complex.crealf16 # libc.src.complex.cimagf16 # libc.src.complex.conjf16 + # libc.src.complex.cprojf16 # math.h C23 _Float16 entrypoints libc.src.math.canonicalizef16 @@ -728,6 +732,7 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.complex.crealf128 libc.src.complex.cimagf128 libc.src.complex.conjf128 + libc.src.complex.cprojf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index f5e9827727396..83f4dfaaa2d0f 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -212,6 +212,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.conj libc.src.complex.conjf libc.src.complex.conjl + libc.src.complex.cproj + libc.src.complex.cprojf + libc.src.complex.cprojl # fenv.h entrypoints libc.src.fenv.feclearexcept diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index e2df6aca38bf9..19980f79e7be8 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -367,6 +367,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.conj libc.src.complex.conjf libc.src.complex.conjl + libc.src.complex.cproj + libc.src.complex.cprojf + libc.src.complex.cprojl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -623,6 +626,7 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.complex.crealf128 libc.src.complex.cimagf128 libc.src.complex.conjf128 + libc.src.complex.cprojf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 68d0501d3d358..c5a2797d607ef 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -370,6 +370,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.conj libc.src.complex.conjf libc.src.complex.conjl + libc.src.complex.cproj + libc.src.complex.cprojf + libc.src.complex.cprojl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -627,6 +630,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.complex.crealf16 libc.src.complex.cimagf16 libc.src.complex.conjf16 + libc.src.complex.cprojf16 # math.h C23 _Float16 entrypoints libc.src.math.canonicalizef16 @@ -737,6 +741,7 @@ if(LIBC_TYPES_HAS_FLOAT128) # libc.src.complex.crealf128 # libc.src.complex.cimagf128 # libc.src.complex.conjf128 + # libc.src.complex.cprojf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 diff --git a/libc/docs/headers/complex.rst b/libc/docs/headers/complex.rst index b6a340543fad1..272cf00c883bc 100644 --- a/libc/docs/headers/complex.rst +++ b/libc/docs/headers/complex.rst @@ -59,7 +59,7 @@ Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | conj | |check| | |check| | |check| | |check| | |check| | 7.3.9.4 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| cproj | | | | | | 7.3.9.5 | N/A | +| cproj | |check| | |check| | |check| | |check| | |check| | 7.3.9.5 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | creal | |check| | |check| | |check| | |check| | |check| | 7.3.9.6 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/hdrgen/yaml/complex.yaml b/libc/hdrgen/yaml/complex.yaml index be0d3c9ae59b4..cd81de7dd9e20 100644 --- a/libc/hdrgen/yaml/complex.yaml +++ b/libc/hdrgen/yaml/complex.yaml @@ -103,3 +103,35 @@ functions: arguments: - type: cfloat128 guard: LIBC_TYPES_HAS_CFLOAT128 + - name: cproj + standards: + - stdc + return_type: _Complex double + arguments: + - type: _Complex double + - name: cprojf + standards: + - stdc + return_type: _Complex float + arguments: + - type: _Complex float + - name: cprojl + standards: + - stdc + return_type: _Complex long double + arguments: + - type: _Complex long double + - name: cprojf16 + standards: + - stdc + return_type: cfloat16 + arguments: + - type: cfloat16 + guard: LIBC_TYPES_HAS_CFLOAT16 + - name: cprojf128 + standards: + - stdc + return_type: cfloat128 + arguments: + - type: cfloat128 + guard: LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 8f85740f70a06..03d83704ad31f 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -235,6 +235,11 @@ add_header_library( complex_type HDRS complex_type.h + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.FPUtil.fp_bits + libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types ) add_header_library( diff --git a/libc/src/__support/complex_type.h b/libc/src/__support/complex_type.h index a6207d38d0eb5..6bb49d6dd2c72 100644 --- a/libc/src/__support/complex_type.h +++ b/libc/src/__support/complex_type.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_COMPLEX_TYPE_H #define LLVM_LIBC_SRC___SUPPORT_COMPLEX_TYPE_H +#include "src/__support/CPP/bit.h" +#include "src/__support/FPUtil/FPBits.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/complex_types.h" #include "src/__support/macros/properties/types.h" @@ -77,5 +79,18 @@ template LIBC_INLINE constexpr T conjugate(T c) { return cpp::bit_cast(c_c); } +template LIBC_INLINE constexpr T project(T c) { + using real_t = make_real_t; + Complex c_c = cpp::bit_cast>(c); + if (fputil::FPBits(c_c.real).is_inf() || + fputil::FPBits(c_c.imag).is_inf()) { + return cpp::bit_cast( + Complex{(fputil::FPBits::inf(Sign::POS).get_val()), + static_cast(c_c.imag > 0 ? 0.0 : -0.0)}); + } else { + return c; + } +} + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC___SUPPORT_COMPLEX_TYPE_H diff --git a/libc/src/complex/CMakeLists.txt b/libc/src/complex/CMakeLists.txt index 7306e2fe925e3..bc66a5445d727 100644 --- a/libc/src/complex/CMakeLists.txt +++ b/libc/src/complex/CMakeLists.txt @@ -30,3 +30,9 @@ add_complex_entrypoint_object(conjf) add_complex_entrypoint_object(conjl) add_complex_entrypoint_object(conjf16) add_complex_entrypoint_object(conjf128) + +add_complex_entrypoint_object(cproj) +add_complex_entrypoint_object(cprojf) +add_complex_entrypoint_object(cprojl) +add_complex_entrypoint_object(cprojf16) +add_complex_entrypoint_object(cprojf128) diff --git a/libc/src/complex/conjf128.h b/libc/src/complex/conjf128.h index 587c979d315ef..c1ae0b03d067a 100644 --- a/libc/src/complex/conjf128.h +++ b/libc/src/complex/conjf128.h @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/__support/macros/properties/complex_types.h" -#include "src/__support/macros/properties/types.h" #if defined(LIBC_TYPES_HAS_CFLOAT128) diff --git a/libc/src/complex/conjf16.h b/libc/src/complex/conjf16.h index b15c5b3f61f4a..685ac8ac5c858 100644 --- a/libc/src/complex/conjf16.h +++ b/libc/src/complex/conjf16.h @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/__support/macros/properties/complex_types.h" -#include "src/__support/macros/properties/types.h" #if defined(LIBC_TYPES_HAS_CFLOAT16) diff --git a/libc/src/complex/cproj.h b/libc/src/complex/cproj.h new file mode 100644 index 0000000000000..62d41bceec3e3 --- /dev/null +++ b/libc/src/complex/cproj.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cproj -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_COMPLEX_CPROJ_H +#define LLVM_LIBC_SRC_COMPLEX_CPROJ_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +_Complex double cproj(_Complex double x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CPROJ_H diff --git a/libc/src/complex/cprojf.h b/libc/src/complex/cprojf.h new file mode 100644 index 0000000000000..76124f9117776 --- /dev/null +++ b/libc/src/complex/cprojf.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cprojf ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_COMPLEX_CPROJF_H +#define LLVM_LIBC_SRC_COMPLEX_CPROJF_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +_Complex float cprojf(_Complex float x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CPROJF_H diff --git a/libc/src/complex/cprojf128.h b/libc/src/complex/cprojf128.h new file mode 100644 index 0000000000000..5f7fe992ef30b --- /dev/null +++ b/libc/src/complex/cprojf128.h @@ -0,0 +1,26 @@ +//===-- Implementation header for cprojf128 ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.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/macros/properties/complex_types.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +#ifndef LLVM_LIBC_SRC_COMPLEX_CPROJF128_H +#define LLVM_LIBC_SRC_COMPLEX_CPROJF128_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +cfloat128 cprojf128(cfloat128 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CPROJF128_H + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/src/complex/cprojf16.h b/libc/src/complex/cprojf16.h new file mode 100644 index 0000000000000..8cce5f0bcef2b --- /dev/null +++ b/libc/src/complex/cprojf16.h @@ -0,0 +1,26 @@ +//===-- Implementation header for cprojf16 ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.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/macros/properties/complex_types.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +#ifndef LLVM_LIBC_SRC_COMPLEX_CPROJF16_H +#define LLVM_LIBC_SRC_COMPLEX_CPROJF16_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +cfloat16 cprojf16(cfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CPROJF16_H + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/src/complex/cprojl.h b/libc/src/complex/cprojl.h new file mode 100644 index 0000000000000..ecc8dce8f8535 --- /dev/null +++ b/libc/src/complex/cprojl.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cprojl ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_COMPLEX_CPROJL_H +#define LLVM_LIBC_SRC_COMPLEX_CPROJL_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +_Complex long double cprojl(_Complex long double x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CPROJL_H diff --git a/libc/src/complex/generic/CMakeLists.txt b/libc/src/complex/generic/CMakeLists.txt index cc14f89122edd..3dae6f8a61495 100644 --- a/libc/src/complex/generic/CMakeLists.txt +++ b/libc/src/complex/generic/CMakeLists.txt @@ -1,3 +1,67 @@ +add_entrypoint_object( + cproj + SRCS + cproj.cpp + HDRS + ../cproj.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.complex_type +) + +add_entrypoint_object( + cprojf + SRCS + cprojf.cpp + HDRS + ../cprojf.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.complex_type +) + +add_entrypoint_object( + cprojl + SRCS + cprojl.cpp + HDRS + ../cprojl.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.complex_type +) + +add_entrypoint_object( + cprojf16 + SRCS + cprojf16.cpp + HDRS + ../cprojf16.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.complex_type + libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types +) + +add_entrypoint_object( + cprojf128 + SRCS + cprojf128.cpp + HDRS + ../cprojf128.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.complex_type + libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types +) + add_entrypoint_object( conj SRCS @@ -7,7 +71,6 @@ add_entrypoint_object( COMPILE_OPTIONS ${libc_opt_high_flag} DEPENDS - libc.src.__support.CPP.bit libc.src.__support.complex_type ) @@ -20,7 +83,6 @@ add_entrypoint_object( COMPILE_OPTIONS ${libc_opt_high_flag} DEPENDS - libc.src.__support.CPP.bit libc.src.__support.complex_type ) @@ -33,7 +95,6 @@ add_entrypoint_object( COMPILE_OPTIONS ${libc_opt_high_flag} DEPENDS - libc.src.__support.CPP.bit libc.src.__support.complex_type ) @@ -46,7 +107,6 @@ add_entrypoint_object( COMPILE_OPTIONS ${libc_opt_high_flag} DEPENDS - libc.src.__support.CPP.bit libc.src.__support.complex_type libc.src.__support.macros.properties.types libc.src.__support.macros.properties.complex_types @@ -61,7 +121,6 @@ add_entrypoint_object( COMPILE_OPTIONS ${libc_opt_high_flag} DEPENDS - libc.src.__support.CPP.bit libc.src.__support.complex_type libc.src.__support.macros.properties.types libc.src.__support.macros.properties.complex_types diff --git a/libc/src/complex/generic/conj.cpp b/libc/src/complex/generic/conj.cpp index 1a93bc25dc3c4..cbcd480d6efa5 100644 --- a/libc/src/complex/generic/conj.cpp +++ b/libc/src/complex/generic/conj.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/complex/conj.h" -#include "src/__support/CPP/bit.h" #include "src/__support/common.h" #include "src/__support/complex_type.h" diff --git a/libc/src/complex/generic/conjf.cpp b/libc/src/complex/generic/conjf.cpp index 33cb34340a04e..a1af3d78ebc6a 100644 --- a/libc/src/complex/generic/conjf.cpp +++ b/libc/src/complex/generic/conjf.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/complex/conjf.h" -#include "src/__support/CPP/bit.h" #include "src/__support/common.h" #include "src/__support/complex_type.h" diff --git a/libc/src/complex/generic/conjf128.cpp b/libc/src/complex/generic/conjf128.cpp index 4e35b3d5a97b7..c65b54849f52e 100644 --- a/libc/src/complex/generic/conjf128.cpp +++ b/libc/src/complex/generic/conjf128.cpp @@ -9,7 +9,6 @@ #include "src/complex/conjf128.h" #if defined(LIBC_TYPES_HAS_CFLOAT128) -#include "src/__support/CPP/bit.h" #include "src/__support/common.h" #include "src/__support/complex_type.h" diff --git a/libc/src/complex/generic/conjf16.cpp b/libc/src/complex/generic/conjf16.cpp index 2564fe252027a..dac11e27b30a2 100644 --- a/libc/src/complex/generic/conjf16.cpp +++ b/libc/src/complex/generic/conjf16.cpp @@ -9,7 +9,6 @@ #include "src/complex/conjf16.h" #if defined(LIBC_TYPES_HAS_CFLOAT16) -#include "src/__support/CPP/bit.h" #include "src/__support/common.h" #include "src/__support/complex_type.h" diff --git a/libc/src/complex/generic/conjl.cpp b/libc/src/complex/generic/conjl.cpp index dc071ab1ec51b..8298ede6fa38f 100644 --- a/libc/src/complex/generic/conjl.cpp +++ b/libc/src/complex/generic/conjl.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/complex/conjl.h" -#include "src/__support/CPP/bit.h" #include "src/__support/common.h" #include "src/__support/complex_type.h" diff --git a/libc/src/complex/generic/cproj.cpp b/libc/src/complex/generic/cproj.cpp new file mode 100644 index 0000000000000..d5e8c3ff3d9ec --- /dev/null +++ b/libc/src/complex/generic/cproj.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of cproj function ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/complex/cproj.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex double, cproj, (_Complex double x)) { + return project<_Complex double>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/complex/generic/cprojf.cpp b/libc/src/complex/generic/cprojf.cpp new file mode 100644 index 0000000000000..d0235f6bfef7e --- /dev/null +++ b/libc/src/complex/generic/cprojf.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of cprojf function ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/complex/cprojf.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex float, cprojf, (_Complex float x)) { + return project<_Complex float>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/complex/generic/cprojf128.cpp b/libc/src/complex/generic/cprojf128.cpp new file mode 100644 index 0000000000000..97134b5523a56 --- /dev/null +++ b/libc/src/complex/generic/cprojf128.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of cprojf128 function ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/complex/cprojf128.h" +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(cfloat128, cprojf128, (cfloat128 x)) { + return project(x); +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/src/complex/generic/cprojf16.cpp b/libc/src/complex/generic/cprojf16.cpp new file mode 100644 index 0000000000000..bd0425ffb5fe5 --- /dev/null +++ b/libc/src/complex/generic/cprojf16.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of cprojf16 function -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/complex/cprojf16.h" +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(cfloat16, cprojf16, (cfloat16 x)) { + return project(x); +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/src/complex/generic/cprojl.cpp b/libc/src/complex/generic/cprojl.cpp new file mode 100644 index 0000000000000..34deeb63b16d0 --- /dev/null +++ b/libc/src/complex/generic/cprojl.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of cprojl function ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/complex/cprojl.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex long double, cprojl, (_Complex long double x)) { + return project<_Complex long double>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/complex/CMakeLists.txt b/libc/test/src/complex/CMakeLists.txt index 0c668d9e1e8b9..d6b62e4686a22 100644 --- a/libc/test/src/complex/CMakeLists.txt +++ b/libc/test/src/complex/CMakeLists.txt @@ -60,6 +60,66 @@ add_libc_test( LibcFPTestHelpers ) +add_libc_test( + cproj_test + SUITE + libc-complex-unittests + SRCS + cproj_test.cpp + DEPENDS + libc.src.complex.cproj + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + cprojf_test + SUITE + libc-complex-unittests + SRCS + cprojf_test.cpp + DEPENDS + libc.src.complex.cprojf + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + cprojl_test + SUITE + libc-complex-unittests + SRCS + cprojl_test.cpp + DEPENDS + libc.src.complex.cprojl + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + cprojf16_test + SUITE + libc-complex-unittests + SRCS + cprojf16_test.cpp + DEPENDS + libc.src.complex.cprojf16 + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + cprojf128_test + SUITE + libc-complex-unittests + SRCS + cprojf128_test.cpp + DEPENDS + libc.src.complex.cprojf128 + LINK_LIBRARIES + LibcFPTestHelpers +) + add_libc_test( creal_test SUITE diff --git a/libc/test/src/complex/CprojTest.h b/libc/test/src/complex/CprojTest.h new file mode 100644 index 0000000000000..4e2f6cc58a5ae --- /dev/null +++ b/libc/test/src/complex/CprojTest.h @@ -0,0 +1,131 @@ +//===-- Utility class to test different flavors of cproj --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 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_COMPLEX_CPROJTEST_H +#define LLVM_LIBC_TEST_SRC_COMPLEX_CPROJTEST_H + +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +#include "hdr/math_macros.h" + +template +class CprojTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { + + DECLARE_SPECIAL_CONSTANTS(FPT) + +public: + typedef CFPT (*CprojFunc)(CFPT); + + void testSpecialNumbers(CprojFunc func) { + EXPECT_CFP_EQ(func(CFPT(inf + 9024.2442i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(inf - 9024.2442i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf + 8923.124i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf - 8923.124i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(9024.2442 + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(9024.2442 + neg_inf * 1.0i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(inf + neg_inf * 1.0i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(inf + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf + neg_inf * 1.0i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(aNaN + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(aNaN + neg_inf * 1.0i)), CFPT(inf - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(90.24 + inf * 1.0i)), CFPT(inf + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(89.12 + neg_inf * 1.0i)), CFPT(inf - 0.0i)); + + EXPECT_CFP_EQ(func(CFPT(aNaN + 67.123i)), CFPT(aNaN + 67.123i)); + EXPECT_CFP_EQ(func(CFPT(neg_aNaN + 78.319i)), CFPT(neg_aNaN + 78.319i)); + EXPECT_CFP_EQ(func(CFPT(sNaN + 7813.131i)), CFPT(sNaN + 7813.131i)); + EXPECT_CFP_EQ(func(CFPT(neg_sNaN + 7824.152i)), CFPT(neg_sNaN + 7824.152i)); + EXPECT_CFP_EQ(func(CFPT(min_normal + 782.124i)), + CFPT(min_normal + 782.124i)); + EXPECT_CFP_EQ(func(CFPT(max_normal + 2141.2352i)), + CFPT(max_normal + 2141.2352i)); + EXPECT_CFP_EQ(func(CFPT(neg_max_normal + 341.134i)), + CFPT(neg_max_normal + 341.134i)); + EXPECT_CFP_EQ(func(CFPT(min_denormal + 781.142i)), + CFPT(min_denormal + 781.142i)); + EXPECT_CFP_EQ(func(CFPT(neg_min_denormal + 781.134i)), + CFPT(neg_min_denormal + 781.134i)); + EXPECT_CFP_EQ(func(CFPT(max_denormal + 1241.112i)), + CFPT(max_denormal + 1241.112i)); + EXPECT_CFP_EQ(func(CFPT(zero + 121.121i)), CFPT(zero + 121.121i)); + EXPECT_CFP_EQ(func(CFPT(67.123 + aNaN * 1.0i)), CFPT(67.123 + aNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(78.319 + neg_aNaN * 1.0i)), + CFPT(78.319 + neg_aNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(7813.131 + sNaN * 1.0i)), + CFPT(7813.131 + sNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(7824.152 + neg_sNaN * 1.0i)), + CFPT(7824.152 + neg_sNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(782.124 + min_normal * 1.0i)), + CFPT(782.124 + min_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(2141.2352 + max_normal * 1.0i)), + CFPT(2141.2352 + max_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(341.134 + neg_max_normal * 1.0i)), + CFPT(341.134 + neg_max_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(781.142 + min_denormal * 1.0i)), + CFPT(781.142 + min_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(781.134 + neg_min_denormal * 1.0i)), + CFPT(781.134 + neg_min_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(1241.112 + max_denormal * 1.0i)), + CFPT(1241.112 + max_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(121.121 + zero * 1.0i)), + CFPT(121.121 + zero * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0 - 0.0i)), CFPT(0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0 + 0.0i)), CFPT(0.0 + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(-0.0 - 0.0i)), CFPT(-0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(-0.0 + 0.0i)), CFPT(-0.0 + 0.0i)); + } + + void testRoundedNumbers(CprojFunc func) { + EXPECT_CFP_EQ(func((CFPT)(4523.1413 + 12413.1414i)), + CFPT(4523.1413 + 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(-4523.1413 + 12413.1414i)), + CFPT(-4523.1413 + 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(4523.1413 - 12413.1414i)), + CFPT(4523.1413 - 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(-4523.1413 - 12413.1414i)), + CFPT(-4523.1413 - 12413.1414i)); + + EXPECT_CFP_EQ(func((CFPT)(3210.5678 + 9876.5432i)), + CFPT(3210.5678 + 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(-3210.5678 + 9876.5432i)), + CFPT(-3210.5678 + 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(3210.5678 - 9876.5432i)), + CFPT(3210.5678 - 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(-3210.5678 - 9876.5432i)), + CFPT(-3210.5678 - 9876.5432i)); + + EXPECT_CFP_EQ(func((CFPT)(1234.4321 + 4321.1234i)), + CFPT(1234.4321 + 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(-1234.4321 + 4321.1234i)), + CFPT(-1234.4321 + 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(1234.4321 - 4321.1234i)), + CFPT(1234.4321 - 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(-1234.4321 - 4321.1234i)), + CFPT(-1234.4321 - 4321.1234i)); + + EXPECT_CFP_EQ(func((CFPT)(6789.1234 + 8765.6789i)), + CFPT(6789.1234 + 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(-6789.1234 + 8765.6789i)), + CFPT(-6789.1234 + 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(6789.1234 - 8765.6789i)), + CFPT(6789.1234 - 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(-6789.1234 - 8765.6789i)), + CFPT(-6789.1234 - 8765.6789i)); + } +}; + +#define LIST_CPROJ_TESTS(U, T, func) \ + using LlvmLibcCprojTest = CprojTest; \ + TEST_F(LlvmLibcCprojTest, SpecialNumbers) { testSpecialNumbers(&func); } \ + TEST_F(LlvmLibcCprojTest, RoundedNumbers) { testRoundedNumbers(&func); } + +#endif // LLVM_LIBC_TEST_SRC_COMPLEX_CPROJTEST_H diff --git a/libc/test/src/complex/cproj_test.cpp b/libc/test/src/complex/cproj_test.cpp new file mode 100644 index 0000000000000..83e5760f9ca82 --- /dev/null +++ b/libc/test/src/complex/cproj_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for cproj -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CprojTest.h" + +#include "src/complex/cproj.h" + +LIST_CPROJ_TESTS(_Complex double, double, LIBC_NAMESPACE::cproj) diff --git a/libc/test/src/complex/cprojf128_test.cpp b/libc/test/src/complex/cprojf128_test.cpp new file mode 100644 index 0000000000000..75708122260d6 --- /dev/null +++ b/libc/test/src/complex/cprojf128_test.cpp @@ -0,0 +1,17 @@ +//===-- Unittests for cprojf128 -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CprojTest.h" + +#include "src/complex/cprojf128.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +LIST_CPROJ_TESTS(cfloat128, float128, LIBC_NAMESPACE::cprojf128) + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/test/src/complex/cprojf16_test.cpp b/libc/test/src/complex/cprojf16_test.cpp new file mode 100644 index 0000000000000..628cec0dc5d96 --- /dev/null +++ b/libc/test/src/complex/cprojf16_test.cpp @@ -0,0 +1,17 @@ +//===-- Unittests for cprojf16 --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CprojTest.h" + +#include "src/complex/cprojf16.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +LIST_CPROJ_TESTS(cfloat16, float16, LIBC_NAMESPACE::cprojf16) + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/test/src/complex/cprojf_test.cpp b/libc/test/src/complex/cprojf_test.cpp new file mode 100644 index 0000000000000..7123ed4e28d4b --- /dev/null +++ b/libc/test/src/complex/cprojf_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for cprojf ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CprojTest.h" + +#include "src/complex/cprojf.h" + +LIST_CPROJ_TESTS(_Complex float, float, LIBC_NAMESPACE::cprojf) diff --git a/libc/test/src/complex/cprojl_test.cpp b/libc/test/src/complex/cprojl_test.cpp new file mode 100644 index 0000000000000..0858bf460188d --- /dev/null +++ b/libc/test/src/complex/cprojl_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for cprojl ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CprojTest.h" + +#include "src/complex/cprojl.h" + +LIST_CPROJ_TESTS(_Complex long double, long double, LIBC_NAMESPACE::cprojl)