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"
34 * _Qp_add(pz, ox, oy) sets *pz = *ox + *oy.
37 _Qp_add(union longdouble
*pz
, const union longdouble
*ox
,
38 const union longdouble
*oy
)
43 * _Q_add(ox, oy) returns *ox + *oy.
46 _Q_add(const union longdouble
*ox
, const union longdouble
*oy
)
48 #endif /* __sparcv9 */
52 const union longdouble
*x
, *y
;
53 unsigned int xm
, ym
, tm
, fsr
;
55 /* sort so |x| >= |y| */
56 xm
= ox
->l
.msw
& 0x7fffffff;
57 ym
= oy
->l
.msw
& 0x7fffffff;
58 if (ym
> xm
|| ym
== xm
&& (oy
->l
.frac2
> ox
->l
.frac2
||
59 oy
->l
.frac2
== ox
->l
.frac2
&& (oy
->l
.frac3
> ox
->l
.frac3
||
60 oy
->l
.frac3
== ox
->l
.frac3
&& oy
->l
.frac4
> ox
->l
.frac4
))) {
74 /* handle nan and inf cases */
75 if (xm
>= 0x7fff0000) {
77 if (ym
>= 0x7fff0000) {
79 if ((ym
& 0xffff) | y
->l
.frac2
| y
->l
.frac3
|
81 /* y is nan; x must be nan too */
82 /* the following logic implements V9 app. B */
84 /* y is snan, signal invalid */
86 __quad_faddq(ox
, oy
, &Z
);
88 Z
= (xm
& 0x8000)? *y
: *oy
;
90 fsr
= (fsr
& ~FSR_CEXC
) |
96 /* x and y are both qnan */
100 if (!((xm
& 0xffff) | x
->l
.frac2
| x
->l
.frac3
|
102 /* x and y are both inf */
103 if ((x
->l
.msw
^ y
->l
.msw
) & 0x80000000) {
104 /* inf - inf, signal invalid */
106 __quad_faddq(ox
, oy
, &Z
);
108 Z
.l
.msw
= 0x7fffffff;
109 Z
.l
.frac2
= Z
.l
.frac3
=
110 Z
.l
.frac4
= 0xffffffff;
111 fsr
= (fsr
& ~FSR_CEXC
) |
113 __quad_setfsrp(&fsr
);
117 /* inf + inf, return inf */
122 if ((xm
& 0xffff) | x
->l
.frac2
| x
->l
.frac3
| x
->l
.frac4
) {
124 if (!(xm
& 0x8000)) {
125 /* snan, signal invalid */
127 __quad_faddq(ox
, oy
, &Z
);
131 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
133 __quad_setfsrp(&fsr
);
145 /* now x and y are finite and |x| >= |y| */
147 z
.l
.msw
= (x
->l
.msw
& 0x80000000);
148 if ((x
->l
.msw
^ y
->l
.msw
) & 0x80000000)
149 __quad_mag_sub(x
, y
, &z
, &fsr
);
151 __quad_mag_add(x
, y
, &z
, &fsr
);
152 if ((fsr
& FSR_CEXC
) & (fsr
>> 23)) {
153 __quad_setfsrp(&fsr
);
154 __quad_faddq(ox
, oy
, &Z
);
157 fsr
|= (fsr
& 0x1f) << 5;
158 __quad_setfsrp(&fsr
);