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