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