4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 static const double C
[] = {
38 3.66210937500000000000e-04,
39 1.52587890625000000000e-05,
40 1.43051147460937500000e-06,
41 5.96046447753906250000e-08,
42 3.72529029846191406250e-09,
43 2.18278728425502777100e-11,
44 8.52651282912120223045e-14,
45 3.55271367880050092936e-15,
46 1.30104260698260532081e-18,
47 8.67361737988403547206e-19,
48 2.16840434497100886801e-19,
49 3.17637355220362627151e-22,
50 7.75481824268463445192e-26,
51 4.62223186652936604733e-33,
52 9.62964972193617926528e-35,
53 4.70197740328915003187e-38,
54 2.75506488473973634680e-40,
60 #define three2p27 C[3]
63 #define three2m13 C[6]
65 #define three2m21 C[8]
68 #define three2m37 C[11]
69 #define three2m45 C[12]
71 #define three2m61 C[14]
74 #define three2m73 C[17]
75 #define three2m85 C[18]
76 #define three2m109 C[19]
79 #define three2m133 C[22]
81 static const unsigned int
88 * _Qp_div(pz, x, y) sets *pz = *x / *y.
91 _Qp_div(union longdouble
*pz
, const union longdouble
*x
,
92 const union longdouble
*y
)
97 * _Q_div(x, y) returns *x / *y.
100 _Q_div(const union longdouble
*x
, const union longdouble
*y
)
102 #endif /* __sparcv9 */
107 double c
, d
, ry
, xx
[4], yy
[5], zz
[5];
108 unsigned int xm
, ym
, fsr
, lx
, ly
, wx
[3], wy
[3];
109 unsigned int msw
, frac2
, frac3
, frac4
, rm
;
110 int ibit
, ex
, ey
, ez
, sign
;
112 xm
= x
->l
.msw
& 0x7fffffff;
113 ym
= y
->l
.msw
& 0x7fffffff;
114 sign
= (x
->l
.msw
^ y
->l
.msw
) & ~0x7fffffff;
116 __quad_getfsrp(&fsr
);
118 /* handle nan and inf cases */
119 if (xm
>= 0x7fff0000 || ym
>= 0x7fff0000) {
120 /* handle nan cases according to V9 app. B */
121 if (QUAD_ISNAN(*y
)) {
122 if (!(y
->l
.msw
& 0x8000)) {
123 /* snan, signal invalid */
125 __quad_fdivq(x
, y
, &Z
);
129 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
131 __quad_setfsrp(&fsr
);
134 } else if (QUAD_ISNAN(*x
) && !(x
->l
.msw
& 0x8000)) {
135 /* snan, signal invalid */
137 __quad_fdivq(x
, y
, &Z
);
141 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
143 __quad_setfsrp(&fsr
);
150 if (QUAD_ISNAN(*x
)) {
151 if (!(x
->l
.msw
& 0x8000)) {
152 /* snan, signal invalid */
154 __quad_fdivq(x
, y
, &Z
);
158 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
160 __quad_setfsrp(&fsr
);
167 if (xm
== 0x7fff0000) {
169 if (ym
== 0x7fff0000) {
170 /* inf / inf, signal invalid */
172 __quad_fdivq(x
, y
, &Z
);
174 Z
.l
.msw
= 0x7fffffff;
175 Z
.l
.frac2
= Z
.l
.frac3
=
176 Z
.l
.frac4
= 0xffffffff;
177 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
179 __quad_setfsrp(&fsr
);
183 /* inf / finite, return inf */
184 Z
.l
.msw
= sign
| 0x7fff0000;
185 Z
.l
.frac2
= Z
.l
.frac3
= Z
.l
.frac4
= 0;
190 Z
.l
.frac2
= Z
.l
.frac3
= Z
.l
.frac4
= 0;
194 /* handle zero cases */
195 if (xm
== 0 || ym
== 0) {
196 if (QUAD_ISZERO(*x
)) {
197 if (QUAD_ISZERO(*y
)) {
198 /* zero / zero, signal invalid */
200 __quad_fdivq(x
, y
, &Z
);
202 Z
.l
.msw
= 0x7fffffff;
203 Z
.l
.frac2
= Z
.l
.frac3
=
204 Z
.l
.frac4
= 0xffffffff;
205 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
207 __quad_setfsrp(&fsr
);
211 /* zero / nonzero, return zero */
213 Z
.l
.frac2
= Z
.l
.frac3
= Z
.l
.frac4
= 0;
216 if (QUAD_ISZERO(*y
)) {
217 /* nonzero / zero, signal zero divide */
219 __quad_fdivq(x
, y
, &Z
);
221 Z
.l
.msw
= sign
| 0x7fff0000;
222 Z
.l
.frac2
= Z
.l
.frac3
= Z
.l
.frac4
= 0;
223 fsr
= (fsr
& ~FSR_CEXC
) | FSR_DZA
| FSR_DZC
;
224 __quad_setfsrp(&fsr
);
230 /* now x and y are finite, nonzero */
231 __quad_setfsrp(&fsr_re
);
233 /* get their normalized significands and exponents */
234 ex
= (int)(xm
>> 16);
242 if (lx
| (x
->l
.frac2
& 0xfffe0000)) {
247 } else if (x
->l
.frac2
| (x
->l
.frac3
& 0xfffe0000)) {
253 } else if (x
->l
.frac3
| (x
->l
.frac4
& 0xfffe0000)) {
260 wx
[0] = wx
[1] = wx
[2] = 0;
263 while ((lx
& 0x10000) == 0) {
264 lx
= (lx
<< 1) | (wx
[0] >> 31);
265 wx
[0] = (wx
[0] << 1) | (wx
[1] >> 31);
266 wx
[1] = (wx
[1] << 1) | (wx
[2] >> 31);
273 ey
= (int)(ym
>> 16);
281 if (ly
| (y
->l
.frac2
& 0xfffe0000)) {
286 } else if (y
->l
.frac2
| (y
->l
.frac3
& 0xfffe0000)) {
292 } else if (y
->l
.frac3
| (y
->l
.frac4
& 0xfffe0000)) {
299 wy
[0] = wy
[1] = wy
[2] = 0;
302 while ((ly
& 0x10000) == 0) {
303 ly
= (ly
<< 1) | (wy
[0] >> 31);
304 wy
[0] = (wy
[0] << 1) | (wy
[1] >> 31);
305 wy
[1] = (wy
[1] << 1) | (wy
[2] >> 31);
312 /* extract the significands into doubles */
314 xx
[0] = (double)((int)lx
) * c
;
315 yy
[0] = (double)((int)ly
) * c
;
318 xx
[0] += (double)((int)(wx
[0] >> 8)) * c
;
319 yy
[1] = (double)((int)(wy
[0] >> 8)) * c
;
322 xx
[1] = (double)((int)(((wx
[0] << 16) |
323 (wx
[1] >> 16)) & 0xffffff)) * c
;
324 yy
[2] = (double)((int)(((wy
[0] << 16) |
325 (wy
[1] >> 16)) & 0xffffff)) * c
;
328 xx
[2] = (double)((int)(((wx
[1] << 8) |
329 (wx
[2] >> 24)) & 0xffffff)) * c
;
330 yy
[3] = (double)((int)(((wy
[1] << 8) |
331 (wy
[2] >> 24)) & 0xffffff)) * c
;
334 xx
[3] = (double)((int)(wx
[2] & 0xffffff)) * c
;
335 yy
[4] = (double)((int)(wy
[2] & 0xffffff)) * c
;
337 /* approximate the reciprocal of y */
338 ry
= one
/ ((yy
[0] + yy
[1]) + yy
[2]);
340 /* compute the first five "digits" of the quotient */
341 zz
[0] = (ry
* (xx
[0] + xx
[1]) + three2p27
) - three2p27
;
342 xx
[0] = ((xx
[0] - zz
[0] * yy
[0]) - zz
[0] * yy
[1]) + xx
[1];
344 c
= (d
+ three2m13
) - three2m13
;
346 xx
[1] = xx
[2] - (d
- c
);
348 c
= (d
+ three2m37
) - three2m37
;
350 xx
[2] = xx
[3] - (d
- c
);
352 c
= (d
+ three2m61
) - three2m61
;
356 zz
[1] = (ry
* (xx
[0] + xx
[1]) + three2p3
) - three2p3
;
357 xx
[0] = ((xx
[0] - zz
[1] * yy
[0]) - zz
[1] * yy
[1]) + xx
[1];
359 c
= (d
+ three2m37
) - three2m37
;
361 xx
[1] = xx
[2] - (d
- c
);
363 c
= (d
+ three2m61
) - three2m61
;
365 xx
[2] = xx
[3] - (d
- c
);
367 c
= (d
+ three2m85
) - three2m85
;
371 zz
[2] = (ry
* (xx
[0] + xx
[1]) + three2m21
) - three2m21
;
372 xx
[0] = ((xx
[0] - zz
[2] * yy
[0]) - zz
[2] * yy
[1]) + xx
[1];
374 c
= (d
+ three2m61
) - three2m61
;
376 xx
[1] = xx
[2] - (d
- c
);
378 c
= (d
+ three2m85
) - three2m85
;
380 xx
[2] = xx
[3] - (d
- c
);
382 c
= (d
+ three2m109
) - three2m109
;
386 zz
[3] = (ry
* (xx
[0] + xx
[1]) + three2m45
) - three2m45
;
387 xx
[0] = ((xx
[0] - zz
[3] * yy
[0]) - zz
[3] * yy
[1]) + xx
[1];
389 c
= (d
+ three2m85
) - three2m85
;
391 xx
[1] = xx
[2] - (d
- c
);
393 c
= (d
+ three2m109
) - three2m109
;
395 xx
[2] = xx
[3] - (d
- c
);
397 c
= (d
+ three2m133
) - three2m133
;
401 zz
[4] = (ry
* (xx
[0] + xx
[1]) + three2m73
) - three2m73
;
403 /* reduce to three doubles, making sure zz[1] is positive */
404 zz
[0] += zz
[1] - twom48
;
405 zz
[1] = twom48
+ zz
[2] + zz
[3];
408 /* if the third term might lie on a rounding boundary, perturb it */
409 if (zz
[2] == (twom62
+ zz
[2]) - twom62
) {
410 /* here we just need to get the sign of the remainder */
411 c
= (((((xx
[0] - zz
[4] * yy
[0]) - zz
[4] * yy
[1]) + xx
[1]) +
412 (xx
[2] - zz
[4] * yy
[2])) + (xx
[3] - zz
[4] * yy
[3]))
421 * propagate carries/borrows, using round-to-negative-infinity mode
422 * to make all terms nonnegative (note that we can't encounter a
423 * borrow so large that the roundoff is unrepresentable because
424 * we took care to make zz[1] positive above)
426 __quad_setfsrp(&fsr_rn
);
428 zz
[2] += (zz
[1] - c
);
431 zz
[1] += (zz
[0] - c
);
434 /* check for borrow */
443 /* if exponent > 0 strip off integer bit, else denormalize */
450 u
.l
.hi
= (unsigned int)(0x3fe + ez
) << 20;
460 /* the first 48 bits of fraction come from zz[0] */
461 u
.d
= d
= two36
+ zz
[0];
463 zz
[0] -= (d
- two36
);
465 u
.d
= d
= two4
+ zz
[0];
469 /* the next 32 come from zz[0] and zz[1] */
470 u
.d
= d
= twom28
+ (zz
[0] + zz
[1]);
472 zz
[0] -= (d
- twom28
);
474 /* condense the remaining fraction; errors here won't matter */
476 zz
[1] = ((zz
[0] - c
) + zz
[1]) + zz
[2];
479 /* get the last word of fraction */
480 u
.d
= d
= twom60
+ (zz
[0] + zz
[1]);
482 zz
[0] -= (d
- twom60
);
484 /* keep track of what's left for rounding; note that the error */
485 /* in computing c will be non-negative due to rounding mode */
488 /* get the rounding mode, fudging directed rounding modes */
489 /* as though the result were positive */
494 /* round and raise exceptions */
499 /* decide whether to round the fraction up */
500 if (rm
== FSR_RP
|| (rm
== FSR_RN
&& (c
> twom113
||
501 (c
== twom113
&& ((frac4
& 1) || (c
- zz
[0] !=
503 /* round up and renormalize if necessary */
507 if (++msw
== 0x10000) {
514 /* check for under/overflow */
516 if (rm
== FSR_RN
|| rm
== FSR_RP
) {
517 z
.l
.msw
= sign
| 0x7fff0000;
518 z
.l
.frac2
= z
.l
.frac3
= z
.l
.frac4
= 0;
520 z
.l
.msw
= sign
| 0x7ffeffff;
521 z
.l
.frac2
= z
.l
.frac3
= z
.l
.frac4
= 0xffffffff;
523 fsr
|= FSR_OFC
| FSR_NXC
;
525 z
.l
.msw
= sign
| (ez
<< 16) | msw
;
530 /* !ibit => exact result was tiny before rounding, */
531 /* t nonzero => result delivered is inexact */
534 fsr
|= FSR_UFC
| FSR_NXC
;
535 else if (fsr
& FSR_UFM
)
540 if ((fsr
& FSR_CEXC
) & (fsr
>> 23)) {
541 __quad_setfsrp(&fsr
);
542 __quad_fdivq(x
, y
, &Z
);
545 fsr
|= (fsr
& 0x1f) << 5;
546 __quad_setfsrp(&fsr
);