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