1 //===-- Square root of IEEE 754 floating point numbers ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_SQRT_H 10 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_SQRT_H 11 12 #include "src/__support/macros/properties/architectures.h" 13 #include "src/__support/macros/properties/cpu_features.h" 14 15 #include "src/__support/FPUtil/generic/sqrt.h" 16 17 // Generic instruction specializations with __builtin_elementwise_sqrt. 18 #if defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT) || \ 19 defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) 20 21 #if __has_builtin(__builtin_elementwise_sqrt) 22 23 namespace LIBC_NAMESPACE_DECL { 24 namespace fputil { 25 26 #ifdef LIBC_TARGET_CPU_HAS_FPU_FLOAT 27 template <> LIBC_INLINE float sqrt<float>(float x) { 28 return __builtin_elementwise_sqrt(x); 29 } 30 #endif // LIBC_TARGET_CPU_HAS_FPU_FLOAT 31 32 #ifdef LIBC_TARGET_CPU_HAS_FPU_DOUBLE 33 template <> LIBC_INLINE double sqrt<double>(double x) { 34 return __builtin_elementwise_sqrt(x); 35 } 36 #endif // LIBC_TARGET_CPU_HAS_FPU_DOUBLE 37 38 // Use 80-bit long double instruction on x86. 39 // https://godbolt.org/z/oWEaj6hxK 40 #ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80 41 template <> LIBC_INLINE long double sqrt<long double>(long double x) { 42 return __builtin_elementwise_sqrt(x); 43 } 44 #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80 45 46 } // namespace fputil 47 } // namespace LIBC_NAMESPACE_DECL 48 49 #else // __builtin_elementwise_sqrt 50 // Use inline assembly when __builtin_elementwise_sqrt is not available. 51 #if defined(LIBC_TARGET_CPU_HAS_SSE2) 52 #include "x86_64/sqrt.h" 53 #elif defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP) 54 #include "aarch64/sqrt.h" 55 #elif defined(LIBC_TARGET_ARCH_IS_ARM) 56 #include "arm/sqrt.h" 57 #elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) 58 #include "riscv/sqrt.h" 59 #endif // Target specific header of inline asm. 60 61 #endif // __builtin_elementwise_sqrt 62 63 #endif // LIBC_TARGET_CPU_HAS_FPU_FLOAT or DOUBLE 64 65 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_SQRT_H 66