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