1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "lint.h"
30 #include <sys/isa_defs.h>
31 #include <floatingpoint.h>
32 #include <limits.h>
33 #include "libc.h"
34
35 /*
36 * Ensure that this "portable" code is only used on big-endian ISAs
37 */
38 #if !defined(_BIG_ENDIAN) || defined(_LITTLE_ENDIAN)
39 #error "big-endian only!"
40 #endif
41
42 /*
43 * Convert a double precision floating point number into a 64-bit int.
44 */
45 long long
__dtoll(double dval)46 __dtoll(double dval)
47 {
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;
57
58 /*
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.
62 */
63 u.d = dval;
64 i0 = u.i[0];
65 i1 = u.i[1];
66
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) {
71 /*
72 * fp_invalid NOT raised if <i0,i1> == LLONG_MIN
73 */
74 if (i0 >= 0 || exp != 63 || (i0 & 0xfffff) != 0 || i1 != 0) {
75 /*
76 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
77 * overflow, Inf, NaN set fp_invalid exception
78 */
79 _fp_current_exceptions |= (1 << (int)fp_invalid);
80 (void) _Q_set_exception(_fp_current_exceptions);
81 }
82 if (i0 < 0)
83 return (LLONG_MIN);
84 else
85 return (LLONG_MAX); /* MAXLONG */
86 }
87
88 /* Extract the mantissa. */
89
90 m0 = 0x40000000 | ((i0 << 10) & 0x3ffffc00) | ((i1 >> 22) & 0x3ff);
91 m1 = i1 << 10;
92
93 /*
94 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
95 * Shift right by (62 - exp) bits.
96 */
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;
112 }
113 break;
114 }
115
116 if (i0 < 0) {
117 m0 = ~m0;
118 m1 = ~m1;
119 if (++m1 == 0)
120 m0++;
121 }
122
123 (void) _Q_set_exception(_fp_current_exceptions);
124 return ((long long)(((unsigned long long)m0 << 32) | m1));
125 }
126
127 /*
128 * Convert a floating point number into a 64-bit int.
129 */
130 long long
__ftoll(float fval)131 __ftoll(float fval)
132 {
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;
142
143 /*
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.
147 */
148 u.f = fval;
149 i0 = u.i;
150
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) {
155 /*
156 * fp_invalid NOT raised if <i0> == LLONG_MIN
157 */
158 if (i0 >= 0 || exp != 63 || (i0 & 0x7fffff) != 0) {
159 /*
160 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
161 * overflow, Inf, NaN set fp_invalid exception
162 */
163 _fp_current_exceptions |= (1 << (int)fp_invalid);
164 (void) _Q_set_exception(_fp_current_exceptions);
165 }
166 if (i0 < 0)
167 return (LLONG_MIN);
168 else
169 return (LLONG_MAX); /* MAXLONG */
170 }
171
172 /* Extract the mantissa. */
173
174 m0 = 0x40000000 | (i0 << 7) & 0x3fffff80;
175 m1 = 0;
176
177 /*
178 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
179 * Shift right by (62 - exp) bits.
180 */
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;
195 }
196 break;
197 }
198
199 if (i0 < 0) {
200 m0 = ~m0;
201 m1 = ~m1;
202 if (++m1 == 0)
203 m0++;
204 }
205
206 (void) _Q_set_exception(_fp_current_exceptions);
207 return ((long long)(((unsigned long long)m0 << 32) | m1));
208 }
209
210 /*
211 * Convert an extended precision floating point number into a 64-bit int.
212 */
213 long long
_Q_qtoll(long double longdbl)214 _Q_qtoll(long double longdbl)
215 {
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;
223
224 /*
225 * Only 96-bits of precision used
226 */
227 i0 = plngdbl[0];
228 i1 = plngdbl[1];
229 i2 = plngdbl[2];
230
231 /*
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.
235 */
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) {
240 /*
241 * fp_invalid NOT raised if <i0,i1,i2,i3> when chopped to
242 * 64 bits == LLONG_MIN
243 */
244 if (i0 >= 0 || exp != 63 || (i0 & 0xffff) != 0 || i1 != 0 ||
245 (i2 & 0xfffe0000) != 0) {
246 /*
247 * abs(x) > MAXLLONG; return {MIN,MAX}LLONG and as
248 * overflow, Inf, NaN set fp_invalid exception
249 */
250 _fp_current_exceptions |= (1 << (int)fp_invalid);
251 (void) _Q_set_exception(_fp_current_exceptions);
252 }
253 if (i0 < 0)
254 return (LLONG_MIN);
255 else
256 return (LLONG_MAX); /* MAXLONG */
257 }
258
259 /* Extract the mantissa. */
260
261 m0 = 0x40000000 | ((i0 << 14) & 0x3fffc000) | ((i1 >> 18) & 0x3fff);
262 m1 = (i1 << 14) | ((i2 >> 18) & 0x3fff);
263
264 /*
265 * The most significant bit of the mantissa is now in bit 62 of m0:m1.
266 * Shift right by (62 - exp) bits.
267 */
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;
283 }
284 break;
285 }
286
287 if (i0 < 0) {
288 m0 = ~m0;
289 m1 = ~m1;
290 if (++m1 == 0)
291 m0++;
292 }
293
294 (void) _Q_set_exception(_fp_current_exceptions);
295 return ((long long)(((unsigned long long)m0 << 32) | m1));
296 }
297