1 /* s_nearbyintl.c -- long double version of s_nearbyint.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  * nearbyintl(x)
17  * Return x rounded to integral value according to the prevailing
18  * rounding mode.
19  * Method:
20  *	Using floating addition.
21  * Exception:
22  *	Inexact flag raised if x not equal to rintl(x).
23  */
24 
25 #include <fenv.h>
26 #include <math.h>
27 #include <math-barriers.h>
28 #include <math_private.h>
29 #include <libm-alias-ldouble.h>
30 #include <math-use-builtins.h>
31 
32 _Float128
__nearbyintl(_Float128 x)33 __nearbyintl (_Float128 x)
34 {
35 #if USE_NEARBYINTL_BUILTIN
36   return __builtin_nearbyintl (x);
37 #else
38   /* Use generic implementation.  */
39   static const _Float128
40     TWO112[2] = {
41 		 L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */
42 		 L(-5.19229685853482762853049632922009600E+33)  /* 0xC06F000000000000, 0 */
43   };
44   fenv_t env;
45   int64_t i0, j0, sx;
46   uint64_t i1 __attribute__ ((unused));
47   _Float128 w, t;
48   GET_LDOUBLE_WORDS64 (i0, i1, x);
49   sx = (((uint64_t) i0) >> 63);
50   j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
51   if (j0 < 112)
52     {
53       if (j0 < 0)
54 	{
55 	  feholdexcept (&env);
56 	  w = TWO112[sx] + math_opt_barrier (x);
57 	  t = w - TWO112[sx];
58 	  math_force_eval (t);
59 	  fesetenv (&env);
60 	  GET_LDOUBLE_MSW64 (i0, t);
61 	  SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63));
62 	  return t;
63 	}
64     }
65   else
66     {
67       if (j0 == 0x4000)
68 	return x + x;		/* inf or NaN  */
69       else
70 	return x;		/* x is integral  */
71     }
72   feholdexcept (&env);
73   w = TWO112[sx] + math_opt_barrier (x);
74   t = w - TWO112[sx];
75   math_force_eval (t);
76   fesetenv (&env);
77   return t;
78 #endif /* ! USE_NEARBYINTL_BUILTIN  */
79 }
80 libm_alias_ldouble (__nearbyint, nearbyint)
81