unistd: Improve fortify with clang
[glibc.git] / sysdeps / ieee754 / flt-32 / s_nearbyintf.c
blobb270749f4cf4066833c138ad8dca55ac6c4f0142
1 /* s_rintf.c -- float version of s_rint.c.
2 */
4 /*
5 * ====================================================
6 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 * Developed at SunPro, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
11 * is preserved.
12 * ====================================================
16 #include <fenv.h>
17 #include <math.h>
18 #include <math-barriers.h>
19 #include <math_private.h>
20 #include <fenv_private.h>
21 #include <libm-alias-float.h>
22 #include <math-use-builtins.h>
24 float
25 __nearbyintf (float x)
27 #if USE_NEARBYINTF_BUILTIN
28 return __builtin_nearbyintf (x);
29 #else
30 /* Use generic implementation. */
31 static const float
32 TWO23[2] = {
33 8.3886080000e+06, /* 0x4b000000 */
34 -8.3886080000e+06, /* 0xcb000000 */
36 fenv_t env;
37 int32_t i0, j0, sx;
38 float w, t;
39 GET_FLOAT_WORD (i0, x);
40 sx = (i0 >> 31) & 1;
41 j0 = ((i0 >> 23) & 0xff) - 0x7f;
42 if (j0 < 23)
44 if (j0 < 0)
46 libc_feholdexceptf (&env);
47 w = TWO23[sx] + math_opt_barrier (x);
48 t = w - TWO23[sx];
49 math_force_eval (t);
50 libc_fesetenvf (&env);
51 GET_FLOAT_WORD (i0, t);
52 SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31));
53 return t;
56 else
58 if (__glibc_unlikely (j0 == 0x80))
59 return x + x; /* inf or NaN */
60 else
61 return x; /* x is integral */
63 libc_feholdexceptf (&env);
64 w = TWO23[sx] + math_opt_barrier (x);
65 t = w - TWO23[sx];
66 math_force_eval (t);
67 libc_fesetenvf (&env);
68 return t;
69 #endif /* ! USE_NEARBYINT_BUILTIN */
71 libm_alias_float (__nearbyint, nearbyint)