import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / port / gen / _ftoll.c
blob857a52b8a1f3648552680ac1e1949ef3bb4a5e67
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "lint.h"
30 #include <sys/isa_defs.h>
31 #include <floatingpoint.h>
32 #include <limits.h>
33 #include "libc.h"
36 * Ensure that this "portable" code is only used on big-endian ISAs
38 #if !defined(_BIG_ENDIAN) || defined(_LITTLE_ENDIAN)
39 #error "big-endian only!"
40 #endif
43 * Convert a double precision floating point number into a 64-bit int.
45 long long
46 __dtoll(double dval)
48 int i0, i1; /* bitslam */
49 int exp; /* exponent */
50 int m0; /* most significant word of mantissa */
51 unsigned int m1; /* least sig. word of mantissa */
52 unsigned int _fp_current_exceptions = 0;
53 union {
54 int i[2];
55 double d;
56 } u;
59 * Extract the exponent and check boundary conditions.
60 * Notice that the exponent is equal to the bit number where
61 * we want the most significant bit to live.
63 u.d = dval;
64 i0 = u.i[0];
65 i1 = u.i[1];
67 exp = ((i0 >> 20) & 0x7ff) - 0x3ff;
68 if (exp < 0) {
69 return ((long long)0); /* abs(x) < 1.0, so round to 0 */
70 } else if (exp > 62) {
72 * fp_invalid NOT raised if <i0,i1> == LLONG_MIN
74 if (i0 >= 0 || exp != 63 || (i0 & 0xfffff) != 0 || i1 != 0) {
76 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
77 * overflow, Inf, NaN set fp_invalid exception
79 _fp_current_exceptions |= (1 << (int)fp_invalid);
80 (void) _Q_set_exception(_fp_current_exceptions);
82 if (i0 < 0)
83 return (LLONG_MIN);
84 else
85 return (LLONG_MAX); /* MAXLONG */
88 /* Extract the mantissa. */
90 m0 = 0x40000000 | ((i0 << 10) & 0x3ffffc00) | ((i1 >> 22) & 0x3ff);
91 m1 = i1 << 10;
94 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
95 * Shift right by (62 - exp) bits.
97 switch (exp) {
98 case 62:
99 break;
100 case 30:
101 m1 = m0;
102 m0 = 0;
103 break;
104 default:
105 if (exp > 30) {
106 m1 = (m0 << (exp - 30)) |
107 (m1 >> (62 - exp)) & ~(-1 << (exp - 30));
108 m0 >>= 62 - exp;
109 } else {
110 m1 = m0 >> (30 - exp);
111 m0 = 0;
113 break;
116 if (i0 < 0) {
117 m0 = ~m0;
118 m1 = ~m1;
119 if (++m1 == 0)
120 m0++;
123 (void) _Q_set_exception(_fp_current_exceptions);
124 return ((long long)(((unsigned long long)m0 << 32) | m1));
128 * Convert a floating point number into a 64-bit int.
130 long long
131 __ftoll(float fval)
133 int i0;
134 int exp; /* exponent */
135 int m0; /* most significant word of mantissa */
136 unsigned int m1; /* least sig. word of mantissa */
137 unsigned int _fp_current_exceptions = 0;
138 union {
139 int i;
140 float f;
141 } u;
144 * Extract the exponent and check boundary conditions.
145 * Notice that the exponent is equal to the bit number where
146 * we want the most significant bit to live.
148 u.f = fval;
149 i0 = u.i;
151 exp = ((i0 >> 23) & 0xff) - 0x7f;
152 if (exp < 0) {
153 return ((long long) 0); /* abs(x) < 1.0, so round to 0 */
154 } else if (exp > 62) {
156 * fp_invalid NOT raised if <i0> == LLONG_MIN
158 if (i0 >= 0 || exp != 63 || (i0 & 0x7fffff) != 0) {
160 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
161 * overflow, Inf, NaN set fp_invalid exception
163 _fp_current_exceptions |= (1 << (int)fp_invalid);
164 (void) _Q_set_exception(_fp_current_exceptions);
166 if (i0 < 0)
167 return (LLONG_MIN);
168 else
169 return (LLONG_MAX); /* MAXLONG */
172 /* Extract the mantissa. */
174 m0 = 0x40000000 | (i0 << 7) & 0x3fffff80;
175 m1 = 0;
178 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
179 * Shift right by (62 - exp) bits.
181 switch (exp) {
182 case 62:
183 break;
184 case 30:
185 m1 = m0;
186 m0 = 0;
187 break;
188 default:
189 if (exp > 30) {
190 m1 = m0 << (exp - 30);
191 m0 >>= 62 - exp;
192 } else {
193 m1 = m0 >> (30 - exp);
194 m0 = 0;
196 break;
199 if (i0 < 0) {
200 m0 = ~m0;
201 m1 = ~m1;
202 if (++m1 == 0)
203 m0++;
206 (void) _Q_set_exception(_fp_current_exceptions);
207 return ((long long)(((unsigned long long)m0 << 32) | m1));
211 * Convert an extended precision floating point number into a 64-bit int.
213 long long
214 _Q_qtoll(long double longdbl)
216 int i0;
217 unsigned int i1, i2; /* a long double is 128-bit in length */
218 int *plngdbl = (int *)&longdbl;
219 int exp; /* exponent */
220 int m0; /* most significant word of mantissa */
221 unsigned int m1; /* least sig. word of mantissa */
222 unsigned int _fp_current_exceptions = 0;
225 * Only 96-bits of precision used
227 i0 = plngdbl[0];
228 i1 = plngdbl[1];
229 i2 = plngdbl[2];
232 * Extract the exponent and check boundary conditions.
233 * Notice that the exponent is equal to the bit number where
234 * we want the most significant bit to live.
236 exp = ((i0 >> 16) & 0x7fff) - 0x3fff;
237 if (exp < 0) {
238 return ((long long)0); /* abs(x) < 1.0, so round to 0 */
239 } else if (exp > 62) {
241 * fp_invalid NOT raised if <i0,i1,i2,i3> when chopped to
242 * 64 bits == LLONG_MIN
244 if (i0 >= 0 || exp != 63 || (i0 & 0xffff) != 0 || i1 != 0 ||
245 (i2 & 0xfffe0000) != 0) {
247 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
248 * overflow, Inf, NaN set fp_invalid exception
250 _fp_current_exceptions |= (1 << (int)fp_invalid);
251 (void) _Q_set_exception(_fp_current_exceptions);
253 if (i0 < 0)
254 return (LLONG_MIN);
255 else
256 return (LLONG_MAX); /* MAXLONG */
259 /* Extract the mantissa. */
261 m0 = 0x40000000 | ((i0 << 14) & 0x3fffc000) | ((i1 >> 18) & 0x3fff);
262 m1 = (i1 << 14) | ((i2 >> 18) & 0x3fff);
265 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
266 * Shift right by (62 - exp) bits.
268 switch (exp) {
269 case 62:
270 break;
271 case 30:
272 m1 = m0;
273 m0 = 0;
274 break;
275 default:
276 if (exp > 30) {
277 m1 = (m0 << (exp - 30)) |
278 (m1 >> (62 - exp)) & ~(-1 << (exp - 30));
279 m0 >>= 62 - exp;
280 } else {
281 m1 = m0 >> (30 - exp);
282 m0 = 0;
284 break;
287 if (i0 < 0) {
288 m0 = ~m0;
289 m1 = ~m1;
290 if (++m1 == 0)
291 m0++;
294 (void) _Q_set_exception(_fp_current_exceptions);
295 return ((long long)(((unsigned long long)m0 << 32) | m1));