1 //===--- Round floating point to nearest integer on x86-64 ------*- 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_X86_64_NEAREST_INTEGER_H 10 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H 11 12 #include "src/__support/common.h" 13 #include "src/__support/macros/config.h" 14 #include "src/__support/macros/properties/architectures.h" 15 16 #if !defined(LIBC_TARGET_ARCH_IS_X86_64) 17 #error "Invalid include" 18 #endif 19 20 #if !defined(__SSE4_2__) 21 #error "SSE4.2 instruction set is not supported" 22 #endif 23 24 #include <immintrin.h> 25 26 namespace LIBC_NAMESPACE_DECL { 27 namespace fputil { 28 nearest_integer(float x)29LIBC_INLINE float nearest_integer(float x) { 30 __m128 xmm = _mm_set_ss(x); // NOLINT 31 __m128 ymm = 32 _mm_round_ss(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT 33 return ymm[0]; 34 } 35 nearest_integer(double x)36LIBC_INLINE double nearest_integer(double x) { 37 __m128d xmm = _mm_set_sd(x); // NOLINT 38 __m128d ymm = 39 _mm_round_sd(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT 40 return ymm[0]; 41 } 42 43 } // namespace fputil 44 } // namespace LIBC_NAMESPACE_DECL 45 46 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H 47