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 # into a 64-bit unsigned int.
44 *
45 * For compatibility with Sun's other conversion routines, pretend result
46 * is signed if input is negative.
47 */
48 unsigned long long
__dtoull(double dval)49 __dtoull(double dval)
50 {
51 int i0; /* bitslam */
52 unsigned i1; /* bitslam */
53 int exp; /* exponent */
54 unsigned int m0; /* most significant word of mantissa */
55 unsigned int m1; /* least sig. word of mantissa */
56 unsigned int _fp_current_exceptions = 0;
57 union {
58 int i[2];
59 double d;
60 } u;
61
62 /*
63 * Extract the exponent and check boundary conditions.
64 * Notice that the exponent is equal to the bit number where
65 * we want the most significant bit to live.
66 */
67 u.d = dval;
68 i0 = u.i[0];
69 i1 = u.i[1];
70
71 exp = ((i0 >> 20) & 0x7ff) - 0x3ff;
72 if (exp < 0) {
73 /* abs(x) < 1.0, so round to 0 */
74 return ((unsigned long long)0);
75 } else if (exp > 63) {
76 /*
77 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as
78 * overflow, Inf, NaN set fp_invalid exception
79 */
80 _fp_current_exceptions |= (1 << (int)fp_invalid);
81 (void) _Q_set_exception(_fp_current_exceptions);
82 if (i0 < 0)
83 return ((unsigned long long)LLONG_MIN);
84 else
85 return (ULLONG_MAX); /* MAXLONG */
86 }
87
88 /* Extract the mantissa. */
89
90 m0 = 0x80000000 | ((i0 << 11) & 0x7ffff800) | ((i1 >> 21) & 0x7ff);
91 m1 = i1 << 11;
92
93 /*
94 * The most significant bit of the mantissa is now in bit 63 of m0:m1.
95 * Shift right by (63 - exp) bits.
96 */
97 switch (exp) {
98 case 63:
99 break;
100 case 31:
101 m1 = m0;
102 m0 = 0;
103 break;
104 default:
105 if (exp > 31) {
106 m1 = (m0 << (exp - 31)) | (m1 >> (63 - exp));
107 m0 = (m0 >> (63 - exp));
108 } else {
109 m1 = (m0 >> (31 - exp));
110 m0 = 0;
111 }
112 break;
113 }
114
115 if (i0 < 0) {
116 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */
117 m0 = 0x80000000;
118 m1 = 0;
119 } else {
120 m0 = ~m0;
121 m1 = ~m1;
122 if (++m1 == 0)
123 m0++;
124 }
125 }
126
127 (void) _Q_set_exception(_fp_current_exceptions);
128 return (((unsigned long long)m0 << 32) | m1);
129 }
130
131 /*
132 * Convert a floating point number into a 64-bit unsigned int.
133 *
134 * For compatibility with Sun's other conversion routines, pretend result
135 * is signed if input is negative.
136 */
137 unsigned long long
__ftoull(float fval)138 __ftoull(float fval)
139 {
140 int i0; /* bitslam */
141 int exp; /* exponent */
142 unsigned int m0; /* most significant word of mantissa */
143 unsigned int m1; /* least sig. word of mantissa */
144 unsigned int _fp_current_exceptions = 0;
145 union {
146 int i;
147 float f;
148 } u;
149
150 /*
151 * Extract the exponent and check boundary conditions.
152 * Notice that the exponent is equal to the bit number where
153 * we want the most significant bit to live.
154 */
155 u.f = fval;
156 i0 = u.i;
157
158 exp = ((i0 >> 23) & 0xff) - 0x7f;
159 if (exp < 0) {
160 /* abs(x) < 1.0, so round to 0 */
161 return ((unsigned long long)0);
162 } else if (exp > 63) {
163 /*
164 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as
165 * overflow, Inf, NaN set fp_invalid exception
166 */
167 _fp_current_exceptions |= (1 << (int)fp_invalid);
168 (void) _Q_set_exception(_fp_current_exceptions);
169 if (i0 < 0)
170 return ((unsigned long long)LLONG_MIN);
171 else
172 return (ULLONG_MAX); /* MAXLONG */
173 }
174
175 /* Extract the mantissa. */
176
177 m0 = 0x80000000 | (i0 << 8) & 0x7fffff00;
178 m1 = 0;
179
180 /*
181 * The most significant bit of the mantissa is now in bit 63 of m0:m1.
182 * Shift right by (63 - exp) bits.
183 */
184 switch (exp) {
185 case 63:
186 break;
187 case 31:
188 m1 = m0;
189 m0 = 0;
190 break;
191 default:
192 if (exp > 31) {
193 m1 = m0 << (exp - 31);
194 m0 = (m0 >> (63 - exp));
195 } else {
196 m1 = (m0 >> (31 - exp));
197 m0 = 0;
198 }
199 break;
200 }
201
202 if (i0 < 0) {
203 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */
204 m0 = 0x80000000;
205 m1 = 0;
206 } else {
207 m0 = ~m0;
208 m1 = ~m1;
209 if (++m1 == 0)
210 m0++;
211 }
212 }
213
214 (void) _Q_set_exception(_fp_current_exceptions);
215 return (((unsigned long long)m0 << 32) | m1);
216 }
217
218 /*
219 * Convert an extended precision floating point # into a 64-bit unsigned int.
220 *
221 * For compatibility with Sun's other conversion routines, pretend result
222 * is signed if input is negative.
223 */
224 unsigned long long
_Q_qtoull(long double ld)225 _Q_qtoull(long double ld)
226 {
227 int i0;
228 unsigned int i1, i2; /* a long double is 128-bit in length */
229 int exp; /* exponent */
230 unsigned int m0; /* most significant word of mantissa */
231 unsigned int m1; /* least sig. word of mantissa */
232 unsigned int _fp_current_exceptions = 0;
233 int *plngdbl = (int *)&ld;
234
235 /* Only 96-bits of precision used */
236 i0 = plngdbl[0];
237 i1 = plngdbl[1];
238 i2 = plngdbl[2];
239
240 /*
241 * Extract the exponent and check boundary conditions.
242 * Notice that the exponent is equal to the bit number where
243 * we want the most significant bit to live.
244 */
245 exp = ((i0 >> 16) & 0x7fff) - 0x3fff;
246 if (exp < 0) {
247 return ((long long)0); /* abs(x) < 1.0, so round to 0 */
248 } else if (exp > 63) {
249 /*
250 * abs(x) > MAXLLONG; return {MIN,MAX}ULLONG and as
251 * overflow, Inf, NaN set fp_invalid exception
252 */
253 _fp_current_exceptions |= (1 << (int)fp_invalid);
254 (void) _Q_set_exception(_fp_current_exceptions);
255 if (i0 < 0)
256 return ((unsigned long long)LLONG_MIN);
257 else
258 return (ULLONG_MAX); /* MAXLONG */
259 }
260
261 /* Extract the mantissa. */
262
263 m0 = 0x80000000 | ((i0<<15) & 0x7fff8000) | ((i1>>17) & 0x7fff);
264 m1 = (i1 << 15) | ((i2 >> 17) & 0x7fff);
265
266 /*
267 * The most significant bit of the mantissa is now in bit 63 of m0:m1.
268 * Shift right by (63 - exp) bits.
269 */
270 switch (exp) {
271 case 63:
272 break;
273 case 31:
274 m1 = m0;
275 m0 = 0;
276 break;
277 default:
278 if (exp > 31) {
279 m1 = (m0 << (exp - 31)) | (m1 >> (63 - exp));
280 m0 = (m0 >> (63 - exp));
281 } else {
282 m1 = (m0 >> (31 - exp));
283 m0 = 0;
284 }
285 break;
286 }
287
288 if (i0 < 0) {
289 if ((int)m0 < 0) { /* x < MINLLONG; return MINLLONG */
290 m0 = 0x80000000;
291 m1 = 0;
292 } else {
293 m0 = ~m0;
294 m1 = ~m1;
295 if (++m1 == 0)
296 m0++;
297 }
298 }
299
300 (void) _Q_set_exception(_fp_current_exceptions);
301 return (((unsigned long long)m0 << 32) | m1);
302 }
303