1 /* Round a float value to a long long in the current rounding mode. 2 Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <math.h> 20 #include <math_private.h> 21 #include <stdint.h> 22 #include <libm-alias-float.h> 23 24 long long int __llrintf(float x)25__llrintf (float x) 26 { 27 #ifdef _ARCH_PWR4 28 /* Assume powerpc64 instructions availability. */ 29 long long int ret; 30 __asm__ ("fctid %0, %1" : "=d" (ret) : "d" (x)); 31 return ret; 32 #else 33 float rx = rintf (x); 34 if (HAVE_PPC_FCTIDZ || rx != x) 35 return (long long int) rx; 36 else 37 { 38 float arx = fabsf (rx); 39 /* Avoid incorrect exceptions from libgcc conversions (as of GCC 40 5): <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>. */ 41 if (arx < 0x1p31f) 42 return (long long int) (long int) rx; 43 else if (!(arx < 0x1p55f)) 44 return (long long int) (long int) (rx * 0x1p-32f) << 32; 45 uint32_t i0; 46 GET_FLOAT_WORD (i0, rx); 47 int exponent = ((i0 >> 23) & 0xff) - 0x7f; 48 unsigned long long int mant = (i0 & 0x7fffff) | 0x800000; 49 mant <<= exponent - 23; 50 return (long long int) ((i0 & 0x80000000) != 0 ? -mant : mant); 51 } 52 #endif 53 } 54 libm_alias_float (__llrint, llrint) 55