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_feq _Qp_feq
33 #define _Q_fne _Qp_fne
34 #define _Q_flt _Qp_flt
35 #define _Q_fle _Qp_fle
36 #define _Q_fgt _Qp_fgt
37 #define _Q_fge _Qp_fge
41 * _Q_feq(x, y) returns nonzero if *x == *y and zero otherwise.
42 * If either *x or *y is a signaling NaN, the invalid operation
43 * exception is raised.
46 _Q_feq(const union longdouble
*x
, const union longdouble
*y
)
50 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
51 if ((QUAD_ISNAN(*x
) && !(x
->l
.msw
& 0x8000)) ||
52 (QUAD_ISNAN(*y
) && !(y
->l
.msw
& 0x8000))) {
53 /* snan, signal invalid */
56 __quad_fcmpq(x
, y
, &fsr
);
57 return (((fsr
>> 10) & 3) == fcc_equal
);
59 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
65 if (QUAD_ISZERO(*x
) && QUAD_ISZERO(*y
))
67 return ((x
->l
.msw
^ y
->l
.msw
| x
->l
.frac2
^ y
->l
.frac2
|
68 x
->l
.frac3
^ y
->l
.frac3
| x
->l
.frac4
^ y
->l
.frac4
) == 0);
72 * _Q_fne(x, y) returns nonzero if *x != *y and zero otherwise.
73 * If either *x or *y is a signaling NaN, the invalid operation
74 * exception is raised.
77 _Q_fne(const union longdouble
*x
, const union longdouble
*y
)
81 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
82 if ((QUAD_ISNAN(*x
) && !(x
->l
.msw
& 0x8000)) ||
83 (QUAD_ISNAN(*y
) && !(y
->l
.msw
& 0x8000))) {
84 /* snan, signal invalid */
87 __quad_fcmpq(x
, y
, &fsr
);
88 return (((fsr
>> 10) & 3) != fcc_equal
);
90 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
94 return (1); /* x != y is TRUE if x or y is NaN */
96 if (QUAD_ISZERO(*x
) && QUAD_ISZERO(*y
))
98 return ((x
->l
.msw
^ y
->l
.msw
| x
->l
.frac2
^ y
->l
.frac2
|
99 x
->l
.frac3
^ y
->l
.frac3
| x
->l
.frac4
^ y
->l
.frac4
) != 0);
103 * _Q_flt(x, y) returns nonzero if *x < *y and zero otherwise. If
104 * either *x or *y is NaN, the invalid operation exception is raised.
107 _Q_flt(const union longdouble
*x
, const union longdouble
*y
)
109 unsigned int xm
, ym
, fsr
;
111 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
112 /* nan, signal invalid */
113 __quad_getfsrp(&fsr
);
115 __quad_fcmpeq(x
, y
, &fsr
);
116 return (((fsr
>> 10) & 3) == fcc_less
);
118 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
119 __quad_setfsrp(&fsr
);
124 /* ignore sign of zero */
132 if ((xm
^ ym
) & 0x80000000) /* x and y have opposite signs */
133 return ((ym
& 0x80000000) == 0);
135 if (xm
& 0x80000000) {
136 return (xm
> ym
|| xm
== ym
&& (x
->l
.frac2
> y
->l
.frac2
||
137 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
> y
->l
.frac3
||
138 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
> y
->l
.frac4
)));
140 return (xm
< ym
|| xm
== ym
&& (x
->l
.frac2
< y
->l
.frac2
||
141 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
< y
->l
.frac3
||
142 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
< y
->l
.frac4
)));
146 * _Q_fle(x, y) returns nonzero if *x <= *y and zero otherwise. If
147 * either *x or *y is NaN, the invalid operation exception is raised.
150 _Q_fle(const union longdouble
*x
, const union longdouble
*y
)
152 unsigned int xm
, ym
, fsr
;
154 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
155 /* nan, signal invalid */
156 __quad_getfsrp(&fsr
);
158 __quad_fcmpeq(x
, y
, &fsr
);
159 fsr
= (fsr
>> 10) & 3;
160 return (fsr
== fcc_less
|| fsr
== fcc_equal
);
162 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
163 __quad_setfsrp(&fsr
);
168 /* ignore sign of zero */
176 if ((xm
^ ym
) & 0x80000000) /* x and y have opposite signs */
177 return ((ym
& 0x80000000) == 0);
179 if (xm
& 0x80000000) {
180 return (xm
> ym
|| xm
== ym
&& (x
->l
.frac2
> y
->l
.frac2
||
181 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
> y
->l
.frac3
||
182 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
>= y
->l
.frac4
)));
184 return (xm
< ym
|| xm
== ym
&& (x
->l
.frac2
< y
->l
.frac2
||
185 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
< y
->l
.frac3
||
186 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
<= y
->l
.frac4
)));
190 * _Q_fgt(x, y) returns nonzero if *x > *y and zero otherwise. If
191 * either *x or *y is NaN, the invalid operation exception is raised.
194 _Q_fgt(const union longdouble
*x
, const union longdouble
*y
)
196 unsigned int xm
, ym
, fsr
;
198 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
199 /* nan, signal invalid */
200 __quad_getfsrp(&fsr
);
202 __quad_fcmpeq(x
, y
, &fsr
);
203 return (((fsr
>> 10) & 3) == fcc_greater
);
205 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
206 __quad_setfsrp(&fsr
);
211 /* ignore sign of zero */
219 if ((xm
^ ym
) & 0x80000000) /* x and y have opposite signs */
220 return ((ym
& 0x80000000) != 0);
222 if (xm
& 0x80000000) {
223 return (xm
< ym
|| xm
== ym
&& (x
->l
.frac2
< y
->l
.frac2
||
224 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
< y
->l
.frac3
||
225 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
< y
->l
.frac4
)));
227 return (xm
> ym
|| xm
== ym
&& (x
->l
.frac2
> y
->l
.frac2
||
228 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
> y
->l
.frac3
||
229 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
> y
->l
.frac4
)));
233 * _Q_fge(x, y) returns nonzero if *x >= *y and zero otherwise. If
234 * either *x or *y is NaN, the invalid operation exception is raised.
237 _Q_fge(const union longdouble
*x
, const union longdouble
*y
)
239 unsigned int xm
, ym
, fsr
;
241 if (QUAD_ISNAN(*x
) || QUAD_ISNAN(*y
)) {
242 /* nan, signal invalid */
243 __quad_getfsrp(&fsr
);
245 __quad_fcmpeq(x
, y
, &fsr
);
246 fsr
= (fsr
>> 10) & 3;
247 return (fsr
== fcc_greater
|| fsr
== fcc_equal
);
249 fsr
= (fsr
& ~FSR_CEXC
) | FSR_NVA
| FSR_NVC
;
250 __quad_setfsrp(&fsr
);
255 /* ignore sign of zero */
263 if ((xm
^ ym
) & 0x80000000) /* x and y have opposite signs */
264 return ((ym
& 0x80000000) != 0);
266 if (xm
& 0x80000000) {
267 return (xm
< ym
|| xm
== ym
&& (x
->l
.frac2
< y
->l
.frac2
||
268 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
< y
->l
.frac3
||
269 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
<= y
->l
.frac4
)));
271 return (xm
> ym
|| xm
== ym
&& (x
->l
.frac2
> y
->l
.frac2
||
272 x
->l
.frac2
== y
->l
.frac2
&& (x
->l
.frac3
> y
->l
.frac3
||
273 x
->l
.frac3
== y
->l
.frac3
&& x
->l
.frac4
>= y
->l
.frac4
)));