1/* s_ceill.c -- long double version of s_ceil.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 * ceill(x)
22 * Return x rounded toward -inf to integral value
23 * Method:
24 * Bit twiddling.
25 */
26
27#define NO_MATH_REDIRECT
28#include <math.h>
29#include <math_private.h>
30#include <libm-alias-ldouble.h>
31#include <math-use-builtins.h>
32
33_Float128
34__ceill (_Float128 x)
35{
36#if USE_CEILL_BUILTIN
37 return __builtin_ceill (x);
38#else
39 /* Use generic implementation. */
40 int64_t i0, i1, j0;
41 uint64_t i, j;
42 GET_LDOUBLE_WORDS64 (i0, i1, x);
43 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
44 if (j0 < 48)
45 {
46 if (j0 < 0)
47 {
48 /* return 0 * sign (x) if |x| < 1 */
49 if (i0 < 0)
50 {
51 i0 = 0x8000000000000000ULL;
52 i1 = 0;
53 }
54 else if ((i0 | i1) != 0)
55 {
56 i0 = 0x3fff000000000000ULL;
57 i1 = 0;
58 }
59 }
60 else
61 {
62 i = (0x0000ffffffffffffULL) >> j0;
63 if (((i0 & i) | i1) == 0)
64 return x; /* x is integral */
65 if (i0 > 0)
66 i0 += (0x0001000000000000LL) >> j0;
67 i0 &= (~i);
68 i1 = 0;
69 }
70 }
71 else if (j0 > 111)
72 {
73 if (j0 == 0x4000)
74 return x + x; /* inf or NaN */
75 else
76 return x; /* x is integral */
77 }
78 else
79 {
80 i = -1ULL >> (j0 - 48);
81 if ((i1 & i) == 0)
82 return x; /* x is integral */
83 if (i0 > 0)
84 {
85 if (j0 == 48)
86 i0 += 1;
87 else
88 {
89 j = i1 + (1LL << (112 - j0));
90 if (j < i1)
91 i0 += 1; /* got a carry */
92 i1 = j;
93 }
94 }
95 i1 &= (~i);
96 }
97 SET_LDOUBLE_WORDS64 (x, i0, i1);
98 return x;
99#endif /* ! USE_CEILL_BUILTIN */
100}
101libm_alias_ldouble (__ceil, ceil)
102