xref: /illumos-gate/usr/src/lib/libm/common/m9x/remquol.c (revision 25c28e83beb90e7c80452a7c818c5e6f73a07dc8)
1*25c28e83SPiotr Jasiukajtis /*
2*25c28e83SPiotr Jasiukajtis  * CDDL HEADER START
3*25c28e83SPiotr Jasiukajtis  *
4*25c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
5*25c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
6*25c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
7*25c28e83SPiotr Jasiukajtis  *
8*25c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*25c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
10*25c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
11*25c28e83SPiotr Jasiukajtis  * and limitations under the License.
12*25c28e83SPiotr Jasiukajtis  *
13*25c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
14*25c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*25c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
16*25c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
17*25c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
18*25c28e83SPiotr Jasiukajtis  *
19*25c28e83SPiotr Jasiukajtis  * CDDL HEADER END
20*25c28e83SPiotr Jasiukajtis  */
21*25c28e83SPiotr Jasiukajtis 
22*25c28e83SPiotr Jasiukajtis /*
23*25c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24*25c28e83SPiotr Jasiukajtis  */
25*25c28e83SPiotr Jasiukajtis /*
26*25c28e83SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27*25c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
28*25c28e83SPiotr Jasiukajtis  */
29*25c28e83SPiotr Jasiukajtis 
30*25c28e83SPiotr Jasiukajtis #pragma weak remquol = __remquol
31*25c28e83SPiotr Jasiukajtis 
32*25c28e83SPiotr Jasiukajtis #include "libm.h"
33*25c28e83SPiotr Jasiukajtis #include "libm_synonyms.h"
34*25c28e83SPiotr Jasiukajtis #if defined(__SUNPRO_C)
35*25c28e83SPiotr Jasiukajtis #include <sunmath.h>			/* fabsl */
36*25c28e83SPiotr Jasiukajtis #endif
37*25c28e83SPiotr Jasiukajtis /* INDENT OFF */
38*25c28e83SPiotr Jasiukajtis static const int
39*25c28e83SPiotr Jasiukajtis 	is = -0x7fffffff - 1,
40*25c28e83SPiotr Jasiukajtis 	im = 0x0000ffff,
41*25c28e83SPiotr Jasiukajtis 	iu = 0x00010000;
42*25c28e83SPiotr Jasiukajtis 
43*25c28e83SPiotr Jasiukajtis static const long double zero = 0.0L, one = 1.0L;
44*25c28e83SPiotr Jasiukajtis /* INDENT ON */
45*25c28e83SPiotr Jasiukajtis 
46*25c28e83SPiotr Jasiukajtis #if defined(__sparc)
47*25c28e83SPiotr Jasiukajtis #define	__H0(x)	((int *) &x)[0]
48*25c28e83SPiotr Jasiukajtis #define	__H1(x)	((int *) &x)[1]
49*25c28e83SPiotr Jasiukajtis #define	__H2(x)	((int *) &x)[2]
50*25c28e83SPiotr Jasiukajtis #define	__H3(x)	((int *) &x)[3]
51*25c28e83SPiotr Jasiukajtis #else
52*25c28e83SPiotr Jasiukajtis #error Unsupported architecture
53*25c28e83SPiotr Jasiukajtis #endif
54*25c28e83SPiotr Jasiukajtis 
55*25c28e83SPiotr Jasiukajtis /*
56*25c28e83SPiotr Jasiukajtis  * On entrance: *quo is initialized to 0, x finite and y non-zero & ordered
57*25c28e83SPiotr Jasiukajtis  */
58*25c28e83SPiotr Jasiukajtis static long double
59*25c28e83SPiotr Jasiukajtis fmodquol(long double x, long double y, int *quo) {
60*25c28e83SPiotr Jasiukajtis 	long double a, b;
61*25c28e83SPiotr Jasiukajtis 	int n, ix, iy, k, sx, sq, m;
62*25c28e83SPiotr Jasiukajtis 	int hx;
63*25c28e83SPiotr Jasiukajtis 	int x0, y0, z0, carry;
64*25c28e83SPiotr Jasiukajtis 	unsigned x1, x2, x3, y1, y2, y3, z1, z2, z3;
65*25c28e83SPiotr Jasiukajtis 
66*25c28e83SPiotr Jasiukajtis 	hx = __H0(x);
67*25c28e83SPiotr Jasiukajtis 	x1 = __H1(x);
68*25c28e83SPiotr Jasiukajtis 	x2 = __H2(x);
69*25c28e83SPiotr Jasiukajtis 	x3 = __H3(x);
70*25c28e83SPiotr Jasiukajtis 	y0 = __H0(y);
71*25c28e83SPiotr Jasiukajtis 	y1 = __H1(y);
72*25c28e83SPiotr Jasiukajtis 	y2 = __H2(y);
73*25c28e83SPiotr Jasiukajtis 	y3 = __H3(y);
74*25c28e83SPiotr Jasiukajtis 
75*25c28e83SPiotr Jasiukajtis 	sx = hx & is;
76*25c28e83SPiotr Jasiukajtis 	sq = (hx ^ y0) & is;
77*25c28e83SPiotr Jasiukajtis 	x0 = hx ^ sx;
78*25c28e83SPiotr Jasiukajtis 	y0 &= ~0x80000000;
79*25c28e83SPiotr Jasiukajtis 
80*25c28e83SPiotr Jasiukajtis 	a = fabsl(x);
81*25c28e83SPiotr Jasiukajtis 	b = fabsl(y);
82*25c28e83SPiotr Jasiukajtis 	if (a <= b) {
83*25c28e83SPiotr Jasiukajtis 		if (a < b)
84*25c28e83SPiotr Jasiukajtis 			return (x);
85*25c28e83SPiotr Jasiukajtis 		else {
86*25c28e83SPiotr Jasiukajtis 			*quo = 1 + (sq >> 30);
87*25c28e83SPiotr Jasiukajtis 			return (zero * x);
88*25c28e83SPiotr Jasiukajtis 		}
89*25c28e83SPiotr Jasiukajtis 	}
90*25c28e83SPiotr Jasiukajtis 	/* determine ix = ilogbl(x) */
91*25c28e83SPiotr Jasiukajtis 	if (x0 < iu) {		/* subnormal x */
92*25c28e83SPiotr Jasiukajtis 		ix = 0;
93*25c28e83SPiotr Jasiukajtis 		ix = -16382;
94*25c28e83SPiotr Jasiukajtis 		while (x0 == 0) {
95*25c28e83SPiotr Jasiukajtis 			ix -= 16;
96*25c28e83SPiotr Jasiukajtis 			x0 = x1 >> 16;
97*25c28e83SPiotr Jasiukajtis 			x1 = (x1 << 16) | (x2 >> 16);
98*25c28e83SPiotr Jasiukajtis 			x2 = (x2 << 16) | (x3 >> 16);
99*25c28e83SPiotr Jasiukajtis 			x3 = (x3 << 16);
100*25c28e83SPiotr Jasiukajtis 		}
101*25c28e83SPiotr Jasiukajtis 		while (x0 < iu) {
102*25c28e83SPiotr Jasiukajtis 			ix -= 1;
103*25c28e83SPiotr Jasiukajtis 			x0 = (x0 << 1) | (x1 >> 31);
104*25c28e83SPiotr Jasiukajtis 			x1 = (x1 << 1) | (x2 >> 31);
105*25c28e83SPiotr Jasiukajtis 			x2 = (x2 << 1) | (x3 >> 31);
106*25c28e83SPiotr Jasiukajtis 			x3 <<= 1;
107*25c28e83SPiotr Jasiukajtis 		}
108*25c28e83SPiotr Jasiukajtis 	} else {
109*25c28e83SPiotr Jasiukajtis 		ix = (x0 >> 16) - 16383;
110*25c28e83SPiotr Jasiukajtis 		x0 = iu | (x0 & im);
111*25c28e83SPiotr Jasiukajtis 	}
112*25c28e83SPiotr Jasiukajtis 
113*25c28e83SPiotr Jasiukajtis 	/* determine iy = ilogbl(y) */
114*25c28e83SPiotr Jasiukajtis 	if (y0 < iu) {		/* subnormal y */
115*25c28e83SPiotr Jasiukajtis 		iy = -16382;
116*25c28e83SPiotr Jasiukajtis 		while (y0 == 0) {
117*25c28e83SPiotr Jasiukajtis 			iy -= 16;
118*25c28e83SPiotr Jasiukajtis 			y0 = y1 >> 16;
119*25c28e83SPiotr Jasiukajtis 			y1 = (y1 << 16) | (y2 >> 16);
120*25c28e83SPiotr Jasiukajtis 			y2 = (y2 << 16) | (y3 >> 16);
121*25c28e83SPiotr Jasiukajtis 			y3 = (y3 << 16);
122*25c28e83SPiotr Jasiukajtis 		}
123*25c28e83SPiotr Jasiukajtis 		while (y0 < iu) {
124*25c28e83SPiotr Jasiukajtis 			iy -= 1;
125*25c28e83SPiotr Jasiukajtis 			y0 = (y0 << 1) | (y1 >> 31);
126*25c28e83SPiotr Jasiukajtis 			y1 = (y1 << 1) | (y2 >> 31);
127*25c28e83SPiotr Jasiukajtis 			y2 = (y2 << 1) | (y3 >> 31);
128*25c28e83SPiotr Jasiukajtis 			y3 <<= 1;
129*25c28e83SPiotr Jasiukajtis 		}
130*25c28e83SPiotr Jasiukajtis 	} else {
131*25c28e83SPiotr Jasiukajtis 		iy = (y0 >> 16) - 16383;
132*25c28e83SPiotr Jasiukajtis 		y0 = iu | (y0 & im);
133*25c28e83SPiotr Jasiukajtis 	}
134*25c28e83SPiotr Jasiukajtis 
135*25c28e83SPiotr Jasiukajtis 
136*25c28e83SPiotr Jasiukajtis 	/* fix point fmod */
137*25c28e83SPiotr Jasiukajtis 	n = ix - iy;
138*25c28e83SPiotr Jasiukajtis 	m = 0;
139*25c28e83SPiotr Jasiukajtis 	while (n--) {
140*25c28e83SPiotr Jasiukajtis 		while (x0 == 0 && n >= 16) {
141*25c28e83SPiotr Jasiukajtis 			m <<= 16;
142*25c28e83SPiotr Jasiukajtis 			n -= 16;
143*25c28e83SPiotr Jasiukajtis 			x0 = x1 >> 16;
144*25c28e83SPiotr Jasiukajtis 			x1 = (x1 << 16) | (x2 >> 16);
145*25c28e83SPiotr Jasiukajtis 			x2 = (x2 << 16) | (x3 >> 16);
146*25c28e83SPiotr Jasiukajtis 			x3 = (x3 << 16);
147*25c28e83SPiotr Jasiukajtis 		}
148*25c28e83SPiotr Jasiukajtis 		while (x0 < iu && n >= 1) {
149*25c28e83SPiotr Jasiukajtis 			m += m;
150*25c28e83SPiotr Jasiukajtis 			n -= 1;
151*25c28e83SPiotr Jasiukajtis 			x0 = (x0 << 1) | (x1 >> 31);
152*25c28e83SPiotr Jasiukajtis 			x1 = (x1 << 1) | (x2 >> 31);
153*25c28e83SPiotr Jasiukajtis 			x2 = (x2 << 1) | (x3 >> 31);
154*25c28e83SPiotr Jasiukajtis 			x3 = (x3 << 1);
155*25c28e83SPiotr Jasiukajtis 		}
156*25c28e83SPiotr Jasiukajtis 		carry = 0;
157*25c28e83SPiotr Jasiukajtis 		z3 = x3 - y3;
158*25c28e83SPiotr Jasiukajtis 		carry = z3 > x3;
159*25c28e83SPiotr Jasiukajtis 		if (carry == 0) {
160*25c28e83SPiotr Jasiukajtis 			z2 = x2 - y2;
161*25c28e83SPiotr Jasiukajtis 			carry = z2 > x2;
162*25c28e83SPiotr Jasiukajtis 		} else {
163*25c28e83SPiotr Jasiukajtis 			z2 = x2 - y2 - 1;
164*25c28e83SPiotr Jasiukajtis 			carry = z2 >= x2;
165*25c28e83SPiotr Jasiukajtis 		}
166*25c28e83SPiotr Jasiukajtis 		if (carry == 0) {
167*25c28e83SPiotr Jasiukajtis 			z1 = x1 - y1;
168*25c28e83SPiotr Jasiukajtis 			carry = z1 > x1;
169*25c28e83SPiotr Jasiukajtis 		} else {
170*25c28e83SPiotr Jasiukajtis 			z1 = x1 - y1 - 1;
171*25c28e83SPiotr Jasiukajtis 			carry = z1 >= x1;
172*25c28e83SPiotr Jasiukajtis 		}
173*25c28e83SPiotr Jasiukajtis 		z0 = x0 - y0 - carry;
174*25c28e83SPiotr Jasiukajtis 		if (z0 < 0) {	/* double x */
175*25c28e83SPiotr Jasiukajtis 			x0 = x0 + x0 + ((x1 & is) != 0);
176*25c28e83SPiotr Jasiukajtis 			x1 = x1 + x1 + ((x2 & is) != 0);
177*25c28e83SPiotr Jasiukajtis 			x2 = x2 + x2 + ((x3 & is) != 0);
178*25c28e83SPiotr Jasiukajtis 			x3 = x3 + x3;
179*25c28e83SPiotr Jasiukajtis 			m += m;
180*25c28e83SPiotr Jasiukajtis 		} else {
181*25c28e83SPiotr Jasiukajtis 			m += 1;
182*25c28e83SPiotr Jasiukajtis 			if (z0 == 0) {
183*25c28e83SPiotr Jasiukajtis 				if ((z1 | z2 | z3) == 0) {
184*25c28e83SPiotr Jasiukajtis 					/* 0: we are done */
185*25c28e83SPiotr Jasiukajtis 					if (n < 31)
186*25c28e83SPiotr Jasiukajtis 						m <<= (1 + n);
187*25c28e83SPiotr Jasiukajtis 					else
188*25c28e83SPiotr Jasiukajtis 						m = 0;
189*25c28e83SPiotr Jasiukajtis 					m &= ~0x80000000;
190*25c28e83SPiotr Jasiukajtis 					*quo = sq >= 0 ? m : -m;
191*25c28e83SPiotr Jasiukajtis 					__H0(a) = hx & is;
192*25c28e83SPiotr Jasiukajtis 					__H1(a) = __H2(a) = __H3(a) = 0;
193*25c28e83SPiotr Jasiukajtis 					return (a);
194*25c28e83SPiotr Jasiukajtis 				}
195*25c28e83SPiotr Jasiukajtis 			}
196*25c28e83SPiotr Jasiukajtis 			/* x = z << 1 */
197*25c28e83SPiotr Jasiukajtis 			z0 = z0 + z0 + ((z1 & is) != 0);
198*25c28e83SPiotr Jasiukajtis 			z1 = z1 + z1 + ((z2 & is) != 0);
199*25c28e83SPiotr Jasiukajtis 			z2 = z2 + z2 + ((z3 & is) != 0);
200*25c28e83SPiotr Jasiukajtis 			z3 = z3 + z3;
201*25c28e83SPiotr Jasiukajtis 			x0 = z0;
202*25c28e83SPiotr Jasiukajtis 			x1 = z1;
203*25c28e83SPiotr Jasiukajtis 			x2 = z2;
204*25c28e83SPiotr Jasiukajtis 			x3 = z3;
205*25c28e83SPiotr Jasiukajtis 			m += m;
206*25c28e83SPiotr Jasiukajtis 		}
207*25c28e83SPiotr Jasiukajtis 	}
208*25c28e83SPiotr Jasiukajtis 	carry = 0;
209*25c28e83SPiotr Jasiukajtis 	z3 = x3 - y3;
210*25c28e83SPiotr Jasiukajtis 	carry = z3 > x3;
211*25c28e83SPiotr Jasiukajtis 	if (carry == 0) {
212*25c28e83SPiotr Jasiukajtis 		z2 = x2 - y2;
213*25c28e83SPiotr Jasiukajtis 		carry = z2 > x2;
214*25c28e83SPiotr Jasiukajtis 	} else {
215*25c28e83SPiotr Jasiukajtis 		z2 = x2 - y2 - 1;
216*25c28e83SPiotr Jasiukajtis 		carry = z2 >= x2;
217*25c28e83SPiotr Jasiukajtis 	}
218*25c28e83SPiotr Jasiukajtis 	if (carry == 0) {
219*25c28e83SPiotr Jasiukajtis 		z1 = x1 - y1;
220*25c28e83SPiotr Jasiukajtis 		carry = z1 > x1;
221*25c28e83SPiotr Jasiukajtis 	} else {
222*25c28e83SPiotr Jasiukajtis 		z1 = x1 - y1 - 1;
223*25c28e83SPiotr Jasiukajtis 		carry = z1 >= x1;
224*25c28e83SPiotr Jasiukajtis 	}
225*25c28e83SPiotr Jasiukajtis 	z0 = x0 - y0 - carry;
226*25c28e83SPiotr Jasiukajtis 	if (z0 >= 0) {
227*25c28e83SPiotr Jasiukajtis 		x0 = z0;
228*25c28e83SPiotr Jasiukajtis 		x1 = z1;
229*25c28e83SPiotr Jasiukajtis 		x2 = z2;
230*25c28e83SPiotr Jasiukajtis 		x3 = z3;
231*25c28e83SPiotr Jasiukajtis 		m += 1;
232*25c28e83SPiotr Jasiukajtis 	}
233*25c28e83SPiotr Jasiukajtis 	m &= ~0x80000000;
234*25c28e83SPiotr Jasiukajtis 	*quo = sq >= 0 ? m : -m;
235*25c28e83SPiotr Jasiukajtis 
236*25c28e83SPiotr Jasiukajtis 	/* convert back to floating value and restore the sign */
237*25c28e83SPiotr Jasiukajtis 	if ((x0 | x1 | x2 | x3) == 0) {
238*25c28e83SPiotr Jasiukajtis 		__H0(a) = hx & is;
239*25c28e83SPiotr Jasiukajtis 		__H1(a) = __H2(a) = __H3(a) = 0;
240*25c28e83SPiotr Jasiukajtis 		return (a);
241*25c28e83SPiotr Jasiukajtis 	}
242*25c28e83SPiotr Jasiukajtis 	while (x0 < iu) {
243*25c28e83SPiotr Jasiukajtis 		if (x0 == 0) {
244*25c28e83SPiotr Jasiukajtis 			iy -= 16;
245*25c28e83SPiotr Jasiukajtis 			x0 = x1 >> 16;
246*25c28e83SPiotr Jasiukajtis 			x1 = (x1 << 16) | (x2 >> 16);
247*25c28e83SPiotr Jasiukajtis 			x2 = (x2 << 16) | (x3 >> 16);
248*25c28e83SPiotr Jasiukajtis 			x3 = (x3 << 16);
249*25c28e83SPiotr Jasiukajtis 		} else {
250*25c28e83SPiotr Jasiukajtis 			x0 = x0 + x0 + ((x1 & is) != 0);
251*25c28e83SPiotr Jasiukajtis 			x1 = x1 + x1 + ((x2 & is) != 0);
252*25c28e83SPiotr Jasiukajtis 			x2 = x2 + x2 + ((x3 & is) != 0);
253*25c28e83SPiotr Jasiukajtis 			x3 = x3 + x3;
254*25c28e83SPiotr Jasiukajtis 			iy -= 1;
255*25c28e83SPiotr Jasiukajtis 		}
256*25c28e83SPiotr Jasiukajtis 	}
257*25c28e83SPiotr Jasiukajtis 
258*25c28e83SPiotr Jasiukajtis 	/* normalize output */
259*25c28e83SPiotr Jasiukajtis 	if (iy >= -16382) {
260*25c28e83SPiotr Jasiukajtis 		__H0(a) = sx | (x0 - iu) | ((iy + 16383) << 16);
261*25c28e83SPiotr Jasiukajtis 		__H1(a) = x1;
262*25c28e83SPiotr Jasiukajtis 		__H2(a) = x2;
263*25c28e83SPiotr Jasiukajtis 		__H3(a) = x3;
264*25c28e83SPiotr Jasiukajtis 	} else {		/* subnormal output */
265*25c28e83SPiotr Jasiukajtis 		n = -16382 - iy;
266*25c28e83SPiotr Jasiukajtis 		k = n & 31;
267*25c28e83SPiotr Jasiukajtis 		if (k <= 16) {
268*25c28e83SPiotr Jasiukajtis 			x3 = (x2 << (32 - k)) | (x3 >> k);
269*25c28e83SPiotr Jasiukajtis 			x2 = (x1 << (32 - k)) | (x2 >> k);
270*25c28e83SPiotr Jasiukajtis 			x1 = (x0 << (32 - k)) | (x1 >> k);
271*25c28e83SPiotr Jasiukajtis 			x0 >>= k;
272*25c28e83SPiotr Jasiukajtis 		} else {
273*25c28e83SPiotr Jasiukajtis 			x3 = (x2 << (32 - k)) | (x3 >> k);
274*25c28e83SPiotr Jasiukajtis 			x2 = (x1 << (32 - k)) | (x2 >> k);
275*25c28e83SPiotr Jasiukajtis 			x1 = (x0 << (32 - k)) | (x1 >> k);
276*25c28e83SPiotr Jasiukajtis 			x0 = 0;
277*25c28e83SPiotr Jasiukajtis 		}
278*25c28e83SPiotr Jasiukajtis 		while (n >= 32) {
279*25c28e83SPiotr Jasiukajtis 			n -= 32;
280*25c28e83SPiotr Jasiukajtis 			x3 = x2;
281*25c28e83SPiotr Jasiukajtis 			x2 = x1;
282*25c28e83SPiotr Jasiukajtis 			x1 = x0;
283*25c28e83SPiotr Jasiukajtis 			x0 = 0;
284*25c28e83SPiotr Jasiukajtis 		}
285*25c28e83SPiotr Jasiukajtis 		__H0(a) = x0 | sx;
286*25c28e83SPiotr Jasiukajtis 		__H1(a) = x1;
287*25c28e83SPiotr Jasiukajtis 		__H2(a) = x2;
288*25c28e83SPiotr Jasiukajtis 		__H3(a) = x3;
289*25c28e83SPiotr Jasiukajtis 		a *= one;
290*25c28e83SPiotr Jasiukajtis 	}
291*25c28e83SPiotr Jasiukajtis 	return (a);
292*25c28e83SPiotr Jasiukajtis }
293*25c28e83SPiotr Jasiukajtis 
294*25c28e83SPiotr Jasiukajtis long double
295*25c28e83SPiotr Jasiukajtis remquol(long double x, long double y, int *quo) {
296*25c28e83SPiotr Jasiukajtis 	int hx, hy, sx, sq;
297*25c28e83SPiotr Jasiukajtis 	long double v;
298*25c28e83SPiotr Jasiukajtis 
299*25c28e83SPiotr Jasiukajtis 	hx = __H0(x);		/* high word of x */
300*25c28e83SPiotr Jasiukajtis 	hy = __H0(y);		/* high word of y */
301*25c28e83SPiotr Jasiukajtis 	sx = hx & is;		/* sign of x */
302*25c28e83SPiotr Jasiukajtis 	sq = (hx ^ hy) & is;	/* sign of x/y */
303*25c28e83SPiotr Jasiukajtis 	hx ^= sx;		/* |x| */
304*25c28e83SPiotr Jasiukajtis 	hy &= ~0x80000000;
305*25c28e83SPiotr Jasiukajtis 
306*25c28e83SPiotr Jasiukajtis 	/* purge off exception values */
307*25c28e83SPiotr Jasiukajtis 	*quo = 0;
308*25c28e83SPiotr Jasiukajtis 	/* y=0, y is NaN, x is NaN or inf */
309*25c28e83SPiotr Jasiukajtis 	if (y == 0.0L || y != y || hx >= 0x7fff0000)
310*25c28e83SPiotr Jasiukajtis 		return ((x * y) / (x * y));
311*25c28e83SPiotr Jasiukajtis 
312*25c28e83SPiotr Jasiukajtis 	y = fabsl(y);
313*25c28e83SPiotr Jasiukajtis 	x = fabsl(x);
314*25c28e83SPiotr Jasiukajtis 	if (hy <= 0x7ffdffff) {
315*25c28e83SPiotr Jasiukajtis 		x = fmodquol(x, y + y, quo);
316*25c28e83SPiotr Jasiukajtis 		*quo = ((*quo) & 0x3fffffff) << 1;
317*25c28e83SPiotr Jasiukajtis 	}
318*25c28e83SPiotr Jasiukajtis 	if (hy < 0x00020000) {
319*25c28e83SPiotr Jasiukajtis 		if (x + x > y) {
320*25c28e83SPiotr Jasiukajtis 			*quo += 1;
321*25c28e83SPiotr Jasiukajtis 			if (x == y)
322*25c28e83SPiotr Jasiukajtis 				x = zero;
323*25c28e83SPiotr Jasiukajtis 			else
324*25c28e83SPiotr Jasiukajtis 				x -= y;
325*25c28e83SPiotr Jasiukajtis 			if (x + x >= y) {
326*25c28e83SPiotr Jasiukajtis 				x -= y;
327*25c28e83SPiotr Jasiukajtis 				*quo += 1;
328*25c28e83SPiotr Jasiukajtis 			}
329*25c28e83SPiotr Jasiukajtis 		}
330*25c28e83SPiotr Jasiukajtis 	} else {
331*25c28e83SPiotr Jasiukajtis 		v = 0.5L * y;
332*25c28e83SPiotr Jasiukajtis 		if (x > v) {
333*25c28e83SPiotr Jasiukajtis 			*quo += 1;
334*25c28e83SPiotr Jasiukajtis 			if (x == y)
335*25c28e83SPiotr Jasiukajtis 				x = zero;
336*25c28e83SPiotr Jasiukajtis 			else
337*25c28e83SPiotr Jasiukajtis 				x -= y;
338*25c28e83SPiotr Jasiukajtis 			if (x >= v) {
339*25c28e83SPiotr Jasiukajtis 				x -= y;
340*25c28e83SPiotr Jasiukajtis 				*quo += 1;
341*25c28e83SPiotr Jasiukajtis 			}
342*25c28e83SPiotr Jasiukajtis 		}
343*25c28e83SPiotr Jasiukajtis 	}
344*25c28e83SPiotr Jasiukajtis 	if (sq != 0)
345*25c28e83SPiotr Jasiukajtis 		*quo = -(*quo);
346*25c28e83SPiotr Jasiukajtis 	return (sx == 0 ? x : -x);
347*25c28e83SPiotr Jasiukajtis }
348