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 (c) 1994-1997, by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
32 #define _Q_qtod _Qp_qtod
36 * _Q_qtod(x) returns (double)*x.
39 _Q_qtod(const union longdouble
*x
)
42 unsigned int xm
, round
, sticky
, fsr
, rm
;
45 xm
= x
->l
.msw
& 0x7fffffff;
47 /* get the rounding mode, fudging directed rounding modes */
48 /* as though the result were positive */
51 if (x
->l
.msw
& 0x80000000)
54 /* handle nan, inf, and out-of-range cases */
55 if (xm
>= 0x43ff0000) {
56 if (xm
>= 0x7fff0000) {
57 if ((xm
& 0xffff) | x
->l
.frac2
| x
->l
.frac3
|
60 u
.l
.hi
= (x
->l
.msw
& 0x80000000) | 0x7ff80000;
61 u
.l
.hi
|= ((xm
& 0x7fff) << 4) |
63 u
.l
.lo
= (x
->l
.frac2
<< 4) |
66 /* snan, signal invalid */
68 __quad_fqtod(x
, &u
.d
);
70 fsr
= (fsr
& ~FSR_CEXC
) |
78 u
.l
.hi
= (x
->l
.msw
& 0x80000000) | 0x7ff00000;
82 /* x is too big, overflow */
83 if (rm
== FSR_RN
|| rm
== FSR_RP
) {
90 u
.l
.hi
|= (x
->l
.msw
& 0x80000000);
91 if (fsr
& (FSR_OFM
| FSR_NXM
)) {
92 __quad_fqtod(x
, &u
.d
);
94 fsr
= (fsr
& ~FSR_CEXC
) | FSR_OFA
| FSR_OFC
|
102 if (xm
< 0x3c010000) {
103 if (xm
< 0x3bcc0000) {
104 if (QUAD_ISZERO(*x
)) {
105 u
.l
.hi
= (x
->l
.msw
& 0x80000000);
109 /* x is too small, underflow */
110 u
.l
.hi
= (x
->l
.msw
& 0x80000000);
111 u
.l
.lo
= ((rm
== FSR_RP
)? 1 : 0);
112 if (fsr
& (FSR_UFM
| FSR_NXM
)) {
113 __quad_fqtod(x
, &u
.d
);
115 fsr
= (fsr
& ~FSR_CEXC
) | FSR_UFA
| FSR_UFC
|
117 __quad_setfsrp(&fsr
);
122 /* x is in the subnormal range for double */
124 u
.l
.hi
= 0x80000 | ((xm
& 0xffff) << 3) | (x
->l
.frac2
>> 29);
125 u
.l
.lo
= (x
->l
.frac2
<< 3) | (x
->l
.frac3
>> 29);
126 round
= x
->l
.frac3
& 0x10000000;
127 sticky
= (x
->l
.frac3
& 0xfffffff) | x
->l
.frac4
;
128 e
= 0x3c00 - (xm
>> 16);
130 sticky
|= round
| (u
.l
.lo
& 0x7fffffff);
131 round
= u
.l
.lo
& 0x80000000;
137 sticky
|= round
| (u
.l
.lo
& ((1 << (e
- 1)) - 1));
138 round
= u
.l
.lo
& (1 << (e
- 1));
139 u
.l
.lo
= (u
.l
.lo
>> e
) | (u
.l
.hi
<< (32 - e
));
143 /* x is in the normal range for double */
144 u
.l
.hi
= ((xm
- 0x3c000000) << 4) | (x
->l
.frac2
>> 28);
145 u
.l
.lo
= (x
->l
.frac2
<< 4) | (x
->l
.frac3
>> 28);
146 round
= x
->l
.frac3
& 0x8000000;
147 sticky
= (x
->l
.frac3
& 0x7ffffff) | x
->l
.frac4
;
150 /* see if we need to round */
152 if (round
| sticky
) {
157 /* round up if necessary */
158 if (rm
== FSR_RP
|| (rm
== FSR_RN
&& round
&& (sticky
||
160 /* round up and check for overflow */
162 if (++u
.l
.hi
>= 0x7ff00000)
167 /* if result is exact and subnormal but underflow trapping is */
168 /* enabled, signal underflow */
169 else if (subnormal
&& (fsr
& FSR_UFM
))
172 /* attach the sign and raise exceptions as need be */
173 u
.l
.hi
|= (x
->l
.msw
& 0x80000000);
174 if ((fsr
& FSR_CEXC
) & (fsr
>> 23)) {
175 __quad_setfsrp(&fsr
);
176 __quad_fqtod(x
, &u
.d
);
178 fsr
|= (fsr
& 0x1f) << 5;
179 __quad_setfsrp(&fsr
);