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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/isa_defs.h>
31 #include <floatingpoint.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!"
43 * Convert a double precision floating point number into a 64-bit int.
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;
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.
67 exp
= ((i0
>> 20) & 0x7ff) - 0x3ff;
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
);
85 return (LLONG_MAX
); /* MAXLONG */
88 /* Extract the mantissa. */
90 m0
= 0x40000000 | ((i0
<< 10) & 0x3ffffc00) | ((i1
>> 22) & 0x3ff);
94 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
95 * Shift right by (62 - exp) bits.
106 m1
= (m0
<< (exp
- 30)) |
107 (m1
>> (62 - exp
)) & ~(-1 << (exp
- 30));
110 m1
= m0
>> (30 - exp
);
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.
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;
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.
151 exp
= ((i0
>> 23) & 0xff) - 0x7f;
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
);
169 return (LLONG_MAX
); /* MAXLONG */
172 /* Extract the mantissa. */
174 m0
= 0x40000000 | (i0
<< 7) & 0x3fffff80;
178 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
179 * Shift right by (62 - exp) bits.
190 m1
= m0
<< (exp
- 30);
193 m1
= m0
>> (30 - exp
);
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.
214 _Q_qtoll(long double longdbl
)
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
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;
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
);
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.
277 m1
= (m0
<< (exp
- 30)) |
278 (m1
>> (62 - exp
)) & ~(-1 << (exp
- 30));
281 m1
= m0
>> (30 - exp
);
294 (void) _Q_set_exception(_fp_current_exceptions
);
295 return ((long long)(((unsigned long long)m0
<< 32) | m1
));