1 /* s_rintf.c -- float version of s_rint.c.
2  */
3 
4 /*
5  * ====================================================
6  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7  *
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  * ====================================================
13  */
14 
15 
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>
23 
24 float
__nearbyintf(float x)25 __nearbyintf (float x)
26 {
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 */
35   };
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)
43     {
44       if (j0 < 0)
45 	{
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;
54 	}
55     }
56   else
57     {
58       if (__glibc_unlikely (j0 == 0x80))
59 	return x + x;		/* inf or NaN  */
60       else
61 	return x;		/* x is integral  */
62   }
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  */
70 }
71 libm_alias_float (__nearbyint, nearbyint)
72