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/properties/architectures.h" 14 15 #if !defined(LIBC_TARGET_ARCH_IS_X86_64) 16 #error "Invalid include" 17 #endif 18 19 #if !defined(__SSE4_2__) 20 #error "SSE4.2 instruction set is not supported" 21 #endif 22 23 #include <immintrin.h> 24 25 namespace LIBC_NAMESPACE { 26 namespace fputil { 27 nearest_integer(float x)28LIBC_INLINE float nearest_integer(float x) { 29 __m128 xmm = _mm_set_ss(x); // NOLINT 30 __m128 ymm = 31 _mm_round_ss(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT 32 return ymm[0]; 33 } 34 nearest_integer(double x)35LIBC_INLINE double nearest_integer(double x) { 36 __m128d xmm = _mm_set_sd(x); // NOLINT 37 __m128d ymm = 38 _mm_round_sd(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT 39 return ymm[0]; 40 } 41 42 } // namespace fputil 43 } // namespace LIBC_NAMESPACE 44 45 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H 46