xref: /titanic_51/usr/src/boot/lib/libstand/qdivrem.c (revision 4a5d661a82b942b6538acd26209d959ce98b593a)
1*4a5d661aSToomas Soome /*-
2*4a5d661aSToomas Soome  * Copyright (c) 1992, 1993
3*4a5d661aSToomas Soome  *	The Regents of the University of California.  All rights reserved.
4*4a5d661aSToomas Soome  *
5*4a5d661aSToomas Soome  * This software was developed by the Computer Systems Engineering group
6*4a5d661aSToomas Soome  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7*4a5d661aSToomas Soome  * contributed to Berkeley.
8*4a5d661aSToomas Soome  *
9*4a5d661aSToomas Soome  * Redistribution and use in source and binary forms, with or without
10*4a5d661aSToomas Soome  * modification, are permitted provided that the following conditions
11*4a5d661aSToomas Soome  * are met:
12*4a5d661aSToomas Soome  * 1. Redistributions of source code must retain the above copyright
13*4a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer.
14*4a5d661aSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
15*4a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
16*4a5d661aSToomas Soome  *    documentation and/or other materials provided with the distribution.
17*4a5d661aSToomas Soome  * 4. Neither the name of the University nor the names of its contributors
18*4a5d661aSToomas Soome  *    may be used to endorse or promote products derived from this software
19*4a5d661aSToomas Soome  *    without specific prior written permission.
20*4a5d661aSToomas Soome  *
21*4a5d661aSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*4a5d661aSToomas Soome  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*4a5d661aSToomas Soome  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*4a5d661aSToomas Soome  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*4a5d661aSToomas Soome  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*4a5d661aSToomas Soome  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*4a5d661aSToomas Soome  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*4a5d661aSToomas Soome  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*4a5d661aSToomas Soome  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*4a5d661aSToomas Soome  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*4a5d661aSToomas Soome  * SUCH DAMAGE.
32*4a5d661aSToomas Soome  *
33*4a5d661aSToomas Soome  * 	From: Id: qdivrem.c,v 1.7 1997/11/07 09:20:40 phk Exp
34*4a5d661aSToomas Soome  */
35*4a5d661aSToomas Soome 
36*4a5d661aSToomas Soome #include <sys/cdefs.h>
37*4a5d661aSToomas Soome __FBSDID("$FreeBSD$");
38*4a5d661aSToomas Soome 
39*4a5d661aSToomas Soome /*
40*4a5d661aSToomas Soome  * Multiprecision divide.  This algorithm is from Knuth vol. 2 (2nd ed),
41*4a5d661aSToomas Soome  * section 4.3.1, pp. 257--259.
42*4a5d661aSToomas Soome  */
43*4a5d661aSToomas Soome 
44*4a5d661aSToomas Soome #include "quad.h"
45*4a5d661aSToomas Soome 
46*4a5d661aSToomas Soome #define	B	(1 << HALF_BITS)	/* digit base */
47*4a5d661aSToomas Soome 
48*4a5d661aSToomas Soome /* Combine two `digits' to make a single two-digit number. */
49*4a5d661aSToomas Soome #define	COMBINE(a, b) (((u_int)(a) << HALF_BITS) | (b))
50*4a5d661aSToomas Soome 
51*4a5d661aSToomas Soome _Static_assert(sizeof(int) / 2 == sizeof(short),
52*4a5d661aSToomas Soome 	"Bitwise functions in libstand are broken on this architecture\n");
53*4a5d661aSToomas Soome 
54*4a5d661aSToomas Soome /* select a type for digits in base B: use unsigned short if they fit */
55*4a5d661aSToomas Soome typedef unsigned short digit;
56*4a5d661aSToomas Soome 
57*4a5d661aSToomas Soome /*
58*4a5d661aSToomas Soome  * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
59*4a5d661aSToomas Soome  * `fall out' the left (there never will be any such anyway).
60*4a5d661aSToomas Soome  * We may assume len >= 0.  NOTE THAT THIS WRITES len+1 DIGITS.
61*4a5d661aSToomas Soome  */
62*4a5d661aSToomas Soome static void
63*4a5d661aSToomas Soome shl(digit *p, int len, int sh)
64*4a5d661aSToomas Soome {
65*4a5d661aSToomas Soome 	int i;
66*4a5d661aSToomas Soome 
67*4a5d661aSToomas Soome 	for (i = 0; i < len; i++)
68*4a5d661aSToomas Soome 		p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
69*4a5d661aSToomas Soome 	p[i] = LHALF(p[i] << sh);
70*4a5d661aSToomas Soome }
71*4a5d661aSToomas Soome 
72*4a5d661aSToomas Soome /*
73*4a5d661aSToomas Soome  * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
74*4a5d661aSToomas Soome  *
75*4a5d661aSToomas Soome  * We do this in base 2-sup-HALF_BITS, so that all intermediate products
76*4a5d661aSToomas Soome  * fit within u_int.  As a consequence, the maximum length dividend and
77*4a5d661aSToomas Soome  * divisor are 4 `digits' in this base (they are shorter if they have
78*4a5d661aSToomas Soome  * leading zeros).
79*4a5d661aSToomas Soome  */
80*4a5d661aSToomas Soome u_quad_t
81*4a5d661aSToomas Soome __qdivrem(uq, vq, arq)
82*4a5d661aSToomas Soome 	u_quad_t uq, vq, *arq;
83*4a5d661aSToomas Soome {
84*4a5d661aSToomas Soome 	union uu tmp;
85*4a5d661aSToomas Soome 	digit *u, *v, *q;
86*4a5d661aSToomas Soome 	digit v1, v2;
87*4a5d661aSToomas Soome 	u_int qhat, rhat, t;
88*4a5d661aSToomas Soome 	int m, n, d, j, i;
89*4a5d661aSToomas Soome 	digit uspace[5], vspace[5], qspace[5];
90*4a5d661aSToomas Soome 
91*4a5d661aSToomas Soome 	/*
92*4a5d661aSToomas Soome 	 * Take care of special cases: divide by zero, and u < v.
93*4a5d661aSToomas Soome 	 */
94*4a5d661aSToomas Soome 	if (vq == 0) {
95*4a5d661aSToomas Soome 		/* divide by zero. */
96*4a5d661aSToomas Soome 		static volatile const unsigned int zero = 0;
97*4a5d661aSToomas Soome 
98*4a5d661aSToomas Soome 		tmp.ul[H] = tmp.ul[L] = 1 / zero;
99*4a5d661aSToomas Soome 		if (arq)
100*4a5d661aSToomas Soome 			*arq = uq;
101*4a5d661aSToomas Soome 		return (tmp.q);
102*4a5d661aSToomas Soome 	}
103*4a5d661aSToomas Soome 	if (uq < vq) {
104*4a5d661aSToomas Soome 		if (arq)
105*4a5d661aSToomas Soome 			*arq = uq;
106*4a5d661aSToomas Soome 		return (0);
107*4a5d661aSToomas Soome 	}
108*4a5d661aSToomas Soome 	u = &uspace[0];
109*4a5d661aSToomas Soome 	v = &vspace[0];
110*4a5d661aSToomas Soome 	q = &qspace[0];
111*4a5d661aSToomas Soome 
112*4a5d661aSToomas Soome 	/*
113*4a5d661aSToomas Soome 	 * Break dividend and divisor into digits in base B, then
114*4a5d661aSToomas Soome 	 * count leading zeros to determine m and n.  When done, we
115*4a5d661aSToomas Soome 	 * will have:
116*4a5d661aSToomas Soome 	 *	u = (u[1]u[2]...u[m+n]) sub B
117*4a5d661aSToomas Soome 	 *	v = (v[1]v[2]...v[n]) sub B
118*4a5d661aSToomas Soome 	 *	v[1] != 0
119*4a5d661aSToomas Soome 	 *	1 < n <= 4 (if n = 1, we use a different division algorithm)
120*4a5d661aSToomas Soome 	 *	m >= 0 (otherwise u < v, which we already checked)
121*4a5d661aSToomas Soome 	 *	m + n = 4
122*4a5d661aSToomas Soome 	 * and thus
123*4a5d661aSToomas Soome 	 *	m = 4 - n <= 2
124*4a5d661aSToomas Soome 	 */
125*4a5d661aSToomas Soome 	tmp.uq = uq;
126*4a5d661aSToomas Soome 	u[0] = 0;
127*4a5d661aSToomas Soome 	u[1] = HHALF(tmp.ul[H]);
128*4a5d661aSToomas Soome 	u[2] = LHALF(tmp.ul[H]);
129*4a5d661aSToomas Soome 	u[3] = HHALF(tmp.ul[L]);
130*4a5d661aSToomas Soome 	u[4] = LHALF(tmp.ul[L]);
131*4a5d661aSToomas Soome 	tmp.uq = vq;
132*4a5d661aSToomas Soome 	v[1] = HHALF(tmp.ul[H]);
133*4a5d661aSToomas Soome 	v[2] = LHALF(tmp.ul[H]);
134*4a5d661aSToomas Soome 	v[3] = HHALF(tmp.ul[L]);
135*4a5d661aSToomas Soome 	v[4] = LHALF(tmp.ul[L]);
136*4a5d661aSToomas Soome 	for (n = 4; v[1] == 0; v++) {
137*4a5d661aSToomas Soome 		if (--n == 1) {
138*4a5d661aSToomas Soome 			u_int rbj;	/* r*B+u[j] (not root boy jim) */
139*4a5d661aSToomas Soome 			digit q1, q2, q3, q4;
140*4a5d661aSToomas Soome 
141*4a5d661aSToomas Soome 			/*
142*4a5d661aSToomas Soome 			 * Change of plan, per exercise 16.
143*4a5d661aSToomas Soome 			 *	r = 0;
144*4a5d661aSToomas Soome 			 *	for j = 1..4:
145*4a5d661aSToomas Soome 			 *		q[j] = floor((r*B + u[j]) / v),
146*4a5d661aSToomas Soome 			 *		r = (r*B + u[j]) % v;
147*4a5d661aSToomas Soome 			 * We unroll this completely here.
148*4a5d661aSToomas Soome 			 */
149*4a5d661aSToomas Soome 			t = v[2];	/* nonzero, by definition */
150*4a5d661aSToomas Soome 			q1 = u[1] / t;
151*4a5d661aSToomas Soome 			rbj = COMBINE(u[1] % t, u[2]);
152*4a5d661aSToomas Soome 			q2 = rbj / t;
153*4a5d661aSToomas Soome 			rbj = COMBINE(rbj % t, u[3]);
154*4a5d661aSToomas Soome 			q3 = rbj / t;
155*4a5d661aSToomas Soome 			rbj = COMBINE(rbj % t, u[4]);
156*4a5d661aSToomas Soome 			q4 = rbj / t;
157*4a5d661aSToomas Soome 			if (arq)
158*4a5d661aSToomas Soome 				*arq = rbj % t;
159*4a5d661aSToomas Soome 			tmp.ul[H] = COMBINE(q1, q2);
160*4a5d661aSToomas Soome 			tmp.ul[L] = COMBINE(q3, q4);
161*4a5d661aSToomas Soome 			return (tmp.q);
162*4a5d661aSToomas Soome 		}
163*4a5d661aSToomas Soome 	}
164*4a5d661aSToomas Soome 
165*4a5d661aSToomas Soome 	/*
166*4a5d661aSToomas Soome 	 * By adjusting q once we determine m, we can guarantee that
167*4a5d661aSToomas Soome 	 * there is a complete four-digit quotient at &qspace[1] when
168*4a5d661aSToomas Soome 	 * we finally stop.
169*4a5d661aSToomas Soome 	 */
170*4a5d661aSToomas Soome 	for (m = 4 - n; u[1] == 0; u++)
171*4a5d661aSToomas Soome 		m--;
172*4a5d661aSToomas Soome 	for (i = 4 - m; --i >= 0;)
173*4a5d661aSToomas Soome 		q[i] = 0;
174*4a5d661aSToomas Soome 	q += 4 - m;
175*4a5d661aSToomas Soome 
176*4a5d661aSToomas Soome 	/*
177*4a5d661aSToomas Soome 	 * Here we run Program D, translated from MIX to C and acquiring
178*4a5d661aSToomas Soome 	 * a few minor changes.
179*4a5d661aSToomas Soome 	 *
180*4a5d661aSToomas Soome 	 * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
181*4a5d661aSToomas Soome 	 */
182*4a5d661aSToomas Soome 	d = 0;
183*4a5d661aSToomas Soome 	for (t = v[1]; t < B / 2; t <<= 1)
184*4a5d661aSToomas Soome 		d++;
185*4a5d661aSToomas Soome 	if (d > 0) {
186*4a5d661aSToomas Soome 		shl(&u[0], m + n, d);		/* u <<= d */
187*4a5d661aSToomas Soome 		shl(&v[1], n - 1, d);		/* v <<= d */
188*4a5d661aSToomas Soome 	}
189*4a5d661aSToomas Soome 	/*
190*4a5d661aSToomas Soome 	 * D2: j = 0.
191*4a5d661aSToomas Soome 	 */
192*4a5d661aSToomas Soome 	j = 0;
193*4a5d661aSToomas Soome 	v1 = v[1];	/* for D3 -- note that v[1..n] are constant */
194*4a5d661aSToomas Soome 	v2 = v[2];	/* for D3 */
195*4a5d661aSToomas Soome 	do {
196*4a5d661aSToomas Soome 		digit uj0, uj1, uj2;
197*4a5d661aSToomas Soome 
198*4a5d661aSToomas Soome 		/*
199*4a5d661aSToomas Soome 		 * D3: Calculate qhat (\^q, in TeX notation).
200*4a5d661aSToomas Soome 		 * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
201*4a5d661aSToomas Soome 		 * let rhat = (u[j]*B + u[j+1]) mod v[1].
202*4a5d661aSToomas Soome 		 * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
203*4a5d661aSToomas Soome 		 * decrement qhat and increase rhat correspondingly.
204*4a5d661aSToomas Soome 		 * Note that if rhat >= B, v[2]*qhat < rhat*B.
205*4a5d661aSToomas Soome 		 */
206*4a5d661aSToomas Soome 		uj0 = u[j + 0];	/* for D3 only -- note that u[j+...] change */
207*4a5d661aSToomas Soome 		uj1 = u[j + 1];	/* for D3 only */
208*4a5d661aSToomas Soome 		uj2 = u[j + 2];	/* for D3 only */
209*4a5d661aSToomas Soome 		if (uj0 == v1) {
210*4a5d661aSToomas Soome 			qhat = B;
211*4a5d661aSToomas Soome 			rhat = uj1;
212*4a5d661aSToomas Soome 			goto qhat_too_big;
213*4a5d661aSToomas Soome 		} else {
214*4a5d661aSToomas Soome 			u_int nn = COMBINE(uj0, uj1);
215*4a5d661aSToomas Soome 			qhat = nn / v1;
216*4a5d661aSToomas Soome 			rhat = nn % v1;
217*4a5d661aSToomas Soome 		}
218*4a5d661aSToomas Soome 		while (v2 * qhat > COMBINE(rhat, uj2)) {
219*4a5d661aSToomas Soome 	qhat_too_big:
220*4a5d661aSToomas Soome 			qhat--;
221*4a5d661aSToomas Soome 			if ((rhat += v1) >= B)
222*4a5d661aSToomas Soome 				break;
223*4a5d661aSToomas Soome 		}
224*4a5d661aSToomas Soome 		/*
225*4a5d661aSToomas Soome 		 * D4: Multiply and subtract.
226*4a5d661aSToomas Soome 		 * The variable `t' holds any borrows across the loop.
227*4a5d661aSToomas Soome 		 * We split this up so that we do not require v[0] = 0,
228*4a5d661aSToomas Soome 		 * and to eliminate a final special case.
229*4a5d661aSToomas Soome 		 */
230*4a5d661aSToomas Soome 		for (t = 0, i = n; i > 0; i--) {
231*4a5d661aSToomas Soome 			t = u[i + j] - v[i] * qhat - t;
232*4a5d661aSToomas Soome 			u[i + j] = LHALF(t);
233*4a5d661aSToomas Soome 			t = (B - HHALF(t)) & (B - 1);
234*4a5d661aSToomas Soome 		}
235*4a5d661aSToomas Soome 		t = u[j] - t;
236*4a5d661aSToomas Soome 		u[j] = LHALF(t);
237*4a5d661aSToomas Soome 		/*
238*4a5d661aSToomas Soome 		 * D5: test remainder.
239*4a5d661aSToomas Soome 		 * There is a borrow if and only if HHALF(t) is nonzero;
240*4a5d661aSToomas Soome 		 * in that (rare) case, qhat was too large (by exactly 1).
241*4a5d661aSToomas Soome 		 * Fix it by adding v[1..n] to u[j..j+n].
242*4a5d661aSToomas Soome 		 */
243*4a5d661aSToomas Soome 		if (HHALF(t)) {
244*4a5d661aSToomas Soome 			qhat--;
245*4a5d661aSToomas Soome 			for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
246*4a5d661aSToomas Soome 				t += u[i + j] + v[i];
247*4a5d661aSToomas Soome 				u[i + j] = LHALF(t);
248*4a5d661aSToomas Soome 				t = HHALF(t);
249*4a5d661aSToomas Soome 			}
250*4a5d661aSToomas Soome 			u[j] = LHALF(u[j] + t);
251*4a5d661aSToomas Soome 		}
252*4a5d661aSToomas Soome 		q[j] = qhat;
253*4a5d661aSToomas Soome 	} while (++j <= m);		/* D7: loop on j. */
254*4a5d661aSToomas Soome 
255*4a5d661aSToomas Soome 	/*
256*4a5d661aSToomas Soome 	 * If caller wants the remainder, we have to calculate it as
257*4a5d661aSToomas Soome 	 * u[m..m+n] >> d (this is at most n digits and thus fits in
258*4a5d661aSToomas Soome 	 * u[m+1..m+n], but we may need more source digits).
259*4a5d661aSToomas Soome 	 */
260*4a5d661aSToomas Soome 	if (arq) {
261*4a5d661aSToomas Soome 		if (d) {
262*4a5d661aSToomas Soome 			for (i = m + n; i > m; --i)
263*4a5d661aSToomas Soome 				u[i] = (u[i] >> d) |
264*4a5d661aSToomas Soome 				    LHALF(u[i - 1] << (HALF_BITS - d));
265*4a5d661aSToomas Soome 			u[i] = 0;
266*4a5d661aSToomas Soome 		}
267*4a5d661aSToomas Soome 		tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
268*4a5d661aSToomas Soome 		tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
269*4a5d661aSToomas Soome 		*arq = tmp.q;
270*4a5d661aSToomas Soome 	}
271*4a5d661aSToomas Soome 
272*4a5d661aSToomas Soome 	tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
273*4a5d661aSToomas Soome 	tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
274*4a5d661aSToomas Soome 	return (tmp.q);
275*4a5d661aSToomas Soome }
276*4a5d661aSToomas Soome 
277*4a5d661aSToomas Soome /*
278*4a5d661aSToomas Soome  * Divide two unsigned quads.
279*4a5d661aSToomas Soome  */
280*4a5d661aSToomas Soome 
281*4a5d661aSToomas Soome u_quad_t
282*4a5d661aSToomas Soome __udivdi3(a, b)
283*4a5d661aSToomas Soome 	u_quad_t a, b;
284*4a5d661aSToomas Soome {
285*4a5d661aSToomas Soome 
286*4a5d661aSToomas Soome 	return (__qdivrem(a, b, (u_quad_t *)0));
287*4a5d661aSToomas Soome }
288*4a5d661aSToomas Soome 
289*4a5d661aSToomas Soome /*
290*4a5d661aSToomas Soome  * Return remainder after dividing two unsigned quads.
291*4a5d661aSToomas Soome  */
292*4a5d661aSToomas Soome u_quad_t
293*4a5d661aSToomas Soome __umoddi3(a, b)
294*4a5d661aSToomas Soome 	u_quad_t a, b;
295*4a5d661aSToomas Soome {
296*4a5d661aSToomas Soome 	u_quad_t r;
297*4a5d661aSToomas Soome 
298*4a5d661aSToomas Soome 	(void)__qdivrem(a, b, &r);
299*4a5d661aSToomas Soome 	return (r);
300*4a5d661aSToomas Soome }
301*4a5d661aSToomas Soome 
302*4a5d661aSToomas Soome /*
303*4a5d661aSToomas Soome  * Divide two signed quads.
304*4a5d661aSToomas Soome  * ??? if -1/2 should produce -1 on this machine, this code is wrong
305*4a5d661aSToomas Soome  */
306*4a5d661aSToomas Soome quad_t
307*4a5d661aSToomas Soome __divdi3(a, b)
308*4a5d661aSToomas Soome         quad_t a, b;
309*4a5d661aSToomas Soome {
310*4a5d661aSToomas Soome 	u_quad_t ua, ub, uq;
311*4a5d661aSToomas Soome 	int neg;
312*4a5d661aSToomas Soome 
313*4a5d661aSToomas Soome 	if (a < 0)
314*4a5d661aSToomas Soome 		ua = -(u_quad_t)a, neg = 1;
315*4a5d661aSToomas Soome 	else
316*4a5d661aSToomas Soome 		ua = a, neg = 0;
317*4a5d661aSToomas Soome 	if (b < 0)
318*4a5d661aSToomas Soome 		ub = -(u_quad_t)b, neg ^= 1;
319*4a5d661aSToomas Soome 	else
320*4a5d661aSToomas Soome 		ub = b;
321*4a5d661aSToomas Soome 	uq = __qdivrem(ua, ub, (u_quad_t *)0);
322*4a5d661aSToomas Soome 	return (neg ? -uq : uq);
323*4a5d661aSToomas Soome }
324*4a5d661aSToomas Soome 
325*4a5d661aSToomas Soome /*
326*4a5d661aSToomas Soome  * Return remainder after dividing two signed quads.
327*4a5d661aSToomas Soome  *
328*4a5d661aSToomas Soome  * XXX
329*4a5d661aSToomas Soome  * If -1/2 should produce -1 on this machine, this code is wrong.
330*4a5d661aSToomas Soome  */
331*4a5d661aSToomas Soome quad_t
332*4a5d661aSToomas Soome __moddi3(a, b)
333*4a5d661aSToomas Soome         quad_t a, b;
334*4a5d661aSToomas Soome {
335*4a5d661aSToomas Soome 	u_quad_t ua, ub, ur;
336*4a5d661aSToomas Soome 	int neg;
337*4a5d661aSToomas Soome 
338*4a5d661aSToomas Soome 	if (a < 0)
339*4a5d661aSToomas Soome 		ua = -(u_quad_t)a, neg = 1;
340*4a5d661aSToomas Soome 	else
341*4a5d661aSToomas Soome 		ua = a, neg = 0;
342*4a5d661aSToomas Soome 	if (b < 0)
343*4a5d661aSToomas Soome 		ub = -(u_quad_t)b;
344*4a5d661aSToomas Soome 	else
345*4a5d661aSToomas Soome 		ub = b;
346*4a5d661aSToomas Soome 	(void)__qdivrem(ua, ub, &ur);
347*4a5d661aSToomas Soome 	return (neg ? -ur : ur);
348*4a5d661aSToomas Soome }
349