1/* s_rintl.c -- long double version of s_rint.c.
2 * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
3 */
4
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#if defined (LIBM_SCCS) && ! defined (lint)
17static char rcsid[] = "$NetBSD: $";
18#endif
19
20/*
21 * rintl(x)
22 * Return x rounded to integral value according to the prevailing
23 * rounding mode.
24 * Method:
25 * Using floating addition.
26 * Exception:
27 * Inexact flag raised if x not equal to rintl(x).
28 */
29
30#define NO_MATH_REDIRECT
31#include <math.h>
32#include <math_private.h>
33#include <libm-alias-ldouble.h>
34#include <math-use-builtins.h>
35
36_Float128
37__rintl (_Float128 x)
38{
39#if USE_RINTL_BUILTIN
40 return __builtin_rintl (x);
41#else
42 /* Use generic implementation. */
43 static const _Float128
44 TWO112[2] = {
45 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
46 -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
47 };
48 int64_t i0, j0, sx;
49 uint64_t i1 __attribute__ ((unused));
50 _Float128 w, t;
51 GET_LDOUBLE_WORDS64 (i0, i1, x);
52 sx = (((uint64_t) i0) >> 63);
53 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
54 if (j0 < 112)
55 {
56 if (j0 < 0)
57 {
58 w = TWO112[sx] + x;
59 t = w - TWO112[sx];
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 w = TWO112[sx] + x;
73 return w - TWO112[sx];
74#endif /* ! USE_RINTL_BUILTIN */
75}
76libm_alias_ldouble (__rint, rint)
77