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_sub(pz, ox, oy) sets *pz = *ox - *oy.
37 _Qp_sub(union longdouble
*pz
, const union longdouble
*ox
,
38 const union longdouble
*oy
)
43 * _Q_sub(ox, oy) returns *ox - *oy.
46 _Q_sub(const union longdouble
*ox
, const union longdouble
*oy
)
48 #endif /* __sparcv9 */
52 const union longdouble
*x
, *y
;
53 unsigned int xm
, ym
, tm
, fsr
;
56 /* sort so |x| >= |y| */
57 xm
= ox
->l
.msw
& 0x7fffffff;
58 ym
= oy
->l
.msw
& 0x7fffffff;
59 if (ym
> xm
|| ym
== xm
&& (oy
->l
.frac2
> ox
->l
.frac2
||
60 oy
->l
.frac2
== ox
->l
.frac2
&& (oy
->l
.frac3
> ox
->l
.frac3
||
61 oy
->l
.frac3
== ox
->l
.frac3
&& oy
->l
.frac4
> ox
->l
.frac4
))) {
77 /* handle nan and inf cases */
78 if (xm
>= 0x7fff0000) {
80 if (ym
>= 0x7fff0000) {
82 if ((ym
& 0xffff) | y
->l
.frac2
| y
->l
.frac3
|
84 /* y is nan; x must be nan too */
85 /* the following logic implements V9 app. B */
87 /* y is snan, signal invalid */
89 __quad_fsubq(ox
, oy
, &Z
);
91 Z
= (xm
& 0x8000)? *y
: *oy
;
93 fsr
= (fsr
& ~FSR_CEXC
) |
99 /* x and y are both qnan */
103 if (!((xm
& 0xffff) | x
->l
.frac2
| x
->l
.frac3
|
105 /* x and y are both inf */
106 if (!((x
->l
.msw
^ y
->l
.msw
) & 0x80000000)) {
107 /* inf - inf, signal invalid */
109 __quad_fsubq(ox
, oy
, &Z
);
111 Z
.l
.msw
= 0x7fffffff;
112 Z
.l
.frac2
= Z
.l
.frac3
=
113 Z
.l
.frac4
= 0xffffffff;
114 fsr
= (fsr
& ~FSR_CEXC
) |
116 __quad_setfsrp(&fsr
);
120 /* inf + inf, return inf */
126 if ((xm
& 0xffff) | x
->l
.frac2
| x
->l
.frac3
| x
->l
.frac4
) {
128 if (!(xm
& 0x8000)) {
129 /* snan, signal invalid */
131 __quad_fsubq(ox
, oy
, &Z
);
135 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
|
137 __quad_setfsrp(&fsr
);
150 /* now x and y are finite and |x| >= |y| */
152 z
.l
.msw
= (x
->l
.msw
& 0x80000000) ^ flip
;
153 if ((x
->l
.msw
^ y
->l
.msw
) & 0x80000000)
154 __quad_mag_add(x
, y
, &z
, &fsr
);
156 __quad_mag_sub(x
, y
, &z
, &fsr
);
157 if ((fsr
& FSR_CEXC
) & (fsr
>> 23)) {
158 __quad_setfsrp(&fsr
);
159 __quad_fsubq(ox
, oy
, &Z
);
162 fsr
|= (fsr
& 0x1f) << 5;
163 __quad_setfsrp(&fsr
);