| /*- | |
| * Copyright (c) 1992, 1993 | |
| * The Regents of the University of California. All rights reserved. | |
| * | |
| * This software was developed by the Computer Systems Engineering group | |
| * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | |
| * contributed to Berkeley. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions | |
| * are met: | |
| * 1. Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * 2. Redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution. | |
| * 4. Neither the name of the University nor the names of its contributors | |
| * may be used to endorse or promote products derived from this software | |
| * without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| * SUCH DAMAGE. | |
| */ | |
| #ifndef _LIBKERN_QUAD_H_ | |
| #define _LIBKERN_QUAD_H_ | |
| /* | |
| * Quad arithmetic. | |
| * | |
| * This library makes the following assumptions: | |
| * | |
| * - The type long long (aka quad_t) exists. | |
| * | |
| * - A quad variable is exactly twice as long as `long'. | |
| * | |
| * - The machine's arithmetic is two's complement. | |
| * | |
| * This library can provide 128-bit arithmetic on a machine with 128-bit | |
| * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines | |
| * with 48-bit longs. | |
| */ | |
| /* | |
| #include <sys/cdefs.h> | |
| #include <sys/types.h> | |
| #include <sys/limits.h> | |
| #include <sys/syslimits.h> | |
| */ | |
| #include <limits.h> | |
| typedef long long quad_t; | |
| typedef unsigned long long u_quad_t; | |
| typedef unsigned long u_long; | |
| #ifndef CHAR_BIT | |
| #define CHAR_BIT __CHAR_BIT__ | |
| #endif | |
| /* | |
| * Define the order of 32-bit words in 64-bit words. | |
| * For little endian only. | |
| */ | |
| #define _QUAD_HIGHWORD 1 | |
| #define _QUAD_LOWWORD 0 | |
| /* | |
| * Depending on the desired operation, we view a `long long' (aka quad_t) in | |
| * one or more of the following formats. | |
| */ | |
| union uu { | |
| quad_t q; /* as a (signed) quad */ | |
| quad_t uq; /* as an unsigned quad */ | |
| long sl[2]; /* as two signed longs */ | |
| u_long ul[2]; /* as two unsigned longs */ | |
| }; | |
| /* | |
| * Define high and low longwords. | |
| */ | |
| #define H _QUAD_HIGHWORD | |
| #define L _QUAD_LOWWORD | |
| /* | |
| * Total number of bits in a quad_t and in the pieces that make it up. | |
| * These are used for shifting, and also below for halfword extraction | |
| * and assembly. | |
| */ | |
| #define QUAD_BITS (sizeof(quad_t) * CHAR_BIT) | |
| #define LONG_BITS (sizeof(long) * CHAR_BIT) | |
| #define HALF_BITS (sizeof(long) * CHAR_BIT / 2) | |
| /* | |
| * Extract high and low shortwords from longword, and move low shortword of | |
| * longword to upper half of long, i.e., produce the upper longword of | |
| * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.) | |
| * | |
| * These are used in the multiply code, to split a longword into upper | |
| * and lower halves, and to reassemble a product as a quad_t, shifted left | |
| * (sizeof(long)*CHAR_BIT/2). | |
| */ | |
| #define HHALF(x) ((x) >> HALF_BITS) | |
| #define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) | |
| #define LHUP(x) ((x) << HALF_BITS) | |
| typedef unsigned int qshift_t; | |
| quad_t __ashldi3(quad_t, qshift_t); | |
| quad_t __ashrdi3(quad_t, qshift_t); | |
| int __cmpdi2(quad_t a, quad_t b); | |
| quad_t __divdi3(quad_t a, quad_t b); | |
| quad_t __lshrdi3(quad_t, qshift_t); | |
| quad_t __moddi3(quad_t a, quad_t b); | |
| u_quad_t __qdivrem(u_quad_t u, u_quad_t v, u_quad_t *rem); | |
| u_quad_t __udivdi3(u_quad_t a, u_quad_t b); | |
| u_quad_t __umoddi3(u_quad_t a, u_quad_t b); | |
| int __ucmpdi2(u_quad_t a, u_quad_t b); | |
| quad_t __divmoddi4(quad_t a, quad_t b, quad_t *rem); | |
| u_quad_t __udivmoddi4(u_quad_t a, u_quad_t b, u_quad_t *rem); | |
| #endif /* !_LIBKERN_QUAD_H_ */ | |
| #if defined (_X86_) && !defined (__x86_64__) | |
| /* | |
| * Shift a (signed) quad value left (arithmetic shift left). | |
| * This is the same as logical shift left! | |
| */ | |
| quad_t | |
| __ashldi3(quad_t a, qshift_t shift) | |
| { | |
| union uu aa; | |
| aa.q = a; | |
| if (shift >= LONG_BITS) { | |
| aa.ul[H] = shift >= QUAD_BITS ? 0 : | |
| aa.ul[L] << (shift - LONG_BITS); | |
| aa.ul[L] = 0; | |
| } else if (shift > 0) { | |
| aa.ul[H] = (aa.ul[H] << shift) | | |
| (aa.ul[L] >> (LONG_BITS - shift)); | |
| aa.ul[L] <<= shift; | |
| } | |
| return (aa.q); | |
| } | |
| /* | |
| * Shift a (signed) quad value right (arithmetic shift right). | |
| */ | |
| quad_t | |
| __ashrdi3(quad_t a, qshift_t shift) | |
| { | |
| union uu aa; | |
| aa.q = a; | |
| if (shift >= LONG_BITS) { | |
| long s; | |
| /* | |
| * Smear bits rightward using the machine's right-shift | |
| * method, whether that is sign extension or zero fill, | |
| * to get the `sign word' s. Note that shifting by | |
| * LONG_BITS is undefined, so we shift (LONG_BITS-1), | |
| * then 1 more, to get our answer. | |
| */ | |
| s = (aa.sl[H] >> (LONG_BITS - 1)) >> 1; | |
| aa.ul[L] = shift >= QUAD_BITS ? s : | |
| aa.sl[H] >> (shift - LONG_BITS); | |
| aa.ul[H] = s; | |
| } else if (shift > 0) { | |
| aa.ul[L] = (aa.ul[L] >> shift) | | |
| (aa.ul[H] << (LONG_BITS - shift)); | |
| aa.sl[H] >>= shift; | |
| } | |
| return (aa.q); | |
| } | |
| /* | |
| * Return 0, 1, or 2 as a <, =, > b respectively. | |
| * Both a and b are considered signed---which means only the high word is | |
| * signed. | |
| */ | |
| int | |
| __cmpdi2(quad_t a, quad_t b) | |
| { | |
| union uu aa, bb; | |
| aa.q = a; | |
| bb.q = b; | |
| return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 : | |
| aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1); | |
| } | |
| /* | |
| * Divide two signed quads. | |
| * ??? if -1/2 should produce -1 on this machine, this code is wrong | |
| */ | |
| quad_t | |
| __divdi3(quad_t a, quad_t b) | |
| { | |
| u_quad_t ua, ub, uq; | |
| int neg; | |
| if (a < 0) | |
| ua = -(u_quad_t)a, neg = 1; | |
| else | |
| ua = a, neg = 0; | |
| if (b < 0) | |
| ub = -(u_quad_t)b, neg ^= 1; | |
| else | |
| ub = b; | |
| uq = __qdivrem(ua, ub, (u_quad_t *)0); | |
| return (neg ? -uq : uq); | |
| } | |
| /* | |
| * Shift an (unsigned) quad value right (logical shift right). | |
| */ | |
| quad_t | |
| __lshrdi3(quad_t a, qshift_t shift) | |
| { | |
| union uu aa; | |
| aa.q = a; | |
| if (shift >= LONG_BITS) { | |
| aa.ul[L] = shift >= QUAD_BITS ? 0 : | |
| aa.ul[H] >> (shift - LONG_BITS); | |
| aa.ul[H] = 0; | |
| } else if (shift > 0) { | |
| aa.ul[L] = (aa.ul[L] >> shift) | | |
| (aa.ul[H] << (LONG_BITS - shift)); | |
| aa.ul[H] >>= shift; | |
| } | |
| return (aa.q); | |
| } | |
| /* | |
| * Return remainder after dividing two signed quads. | |
| * | |
| * XXX | |
| * If -1/2 should produce -1 on this machine, this code is wrong. | |
| */ | |
| quad_t | |
| __moddi3(quad_t a, quad_t b) | |
| { | |
| u_quad_t ua, ub, ur; | |
| int neg; | |
| if (a < 0) | |
| ua = -(u_quad_t)a, neg = 1; | |
| else | |
| ua = a, neg = 0; | |
| if (b < 0) | |
| ub = -(u_quad_t)b; | |
| else | |
| ub = b; | |
| (void)__qdivrem(ua, ub, &ur); | |
| return (neg ? -ur : ur); | |
| } | |
| /* | |
| * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed), | |
| * section 4.3.1, pp. 257--259. | |
| */ | |
| #define B (1 << HALF_BITS) /* digit base */ | |
| /* Combine two `digits' to make a single two-digit number. */ | |
| #define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b)) | |
| /* select a type for digits in base B: use unsigned short if they fit */ | |
| #if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff | |
| typedef unsigned short digit; | |
| #else | |
| typedef u_long digit; | |
| #endif | |
| /* | |
| * Shift p[0]..p[len] left `sh' bits, ignoring any bits that | |
| * `fall out' the left (there never will be any such anyway). | |
| * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS. | |
| */ | |
| static void | |
| __shl(register digit *p, register int len, register int sh) | |
| { | |
| register int i; | |
| for (i = 0; i < len; i++) | |
| p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh)); | |
| p[i] = LHALF(p[i] << sh); | |
| } | |
| /* | |
| * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v. | |
| * | |
| * We do this in base 2-sup-HALF_BITS, so that all intermediate products | |
| * fit within u_long. As a consequence, the maximum length dividend and | |
| * divisor are 4 `digits' in this base (they are shorter if they have | |
| * leading zeros). | |
| */ | |
| u_quad_t | |
| __qdivrem(u_quad_t uq, u_quad_t vq, u_quad_t *arq) | |
| { | |
| union uu tmp; | |
| digit *u, *v, *q; | |
| register digit v1, v2; | |
| u_long qhat, rhat, t; | |
| int m, n, d, j, i; | |
| digit uspace[5], vspace[5], qspace[5]; | |
| /* | |
| * Take care of special cases: divide by zero, and u < v. | |
| */ | |
| if (vq == 0) { | |
| /* divide by zero. */ | |
| static volatile const unsigned int zero = 0; | |
| tmp.ul[H] = tmp.ul[L] = 1 / zero; | |
| if (arq) | |
| *arq = uq; | |
| return (tmp.q); | |
| } | |
| if (uq < vq) { | |
| if (arq) | |
| *arq = uq; | |
| return (0); | |
| } | |
| u = &uspace[0]; | |
| v = &vspace[0]; | |
| q = &qspace[0]; | |
| /* | |
| * Break dividend and divisor into digits in base B, then | |
| * count leading zeros to determine m and n. When done, we | |
| * will have: | |
| * u = (u[1]u[2]...u[m+n]) sub B | |
| * v = (v[1]v[2]...v[n]) sub B | |
| * v[1] != 0 | |
| * 1 < n <= 4 (if n = 1, we use a different division algorithm) | |
| * m >= 0 (otherwise u < v, which we already checked) | |
| * m + n = 4 | |
| * and thus | |
| * m = 4 - n <= 2 | |
| */ | |
| tmp.uq = uq; | |
| u[0] = 0; | |
| u[1] = HHALF(tmp.ul[H]); | |
| u[2] = LHALF(tmp.ul[H]); | |
| u[3] = HHALF(tmp.ul[L]); | |
| u[4] = LHALF(tmp.ul[L]); | |
| tmp.uq = vq; | |
| v[1] = HHALF(tmp.ul[H]); | |
| v[2] = LHALF(tmp.ul[H]); | |
| v[3] = HHALF(tmp.ul[L]); | |
| v[4] = LHALF(tmp.ul[L]); | |
| for (n = 4; v[1] == 0; v++) { | |
| if (--n == 1) { | |
| u_long rbj; /* r*B+u[j] (not root boy jim) */ | |
| digit q1, q2, q3, q4; | |
| /* | |
| * Change of plan, per exercise 16. | |
| * r = 0; | |
| * for j = 1..4: | |
| * q[j] = floor((r*B + u[j]) / v), | |
| * r = (r*B + u[j]) % v; | |
| * We unroll this completely here. | |
| */ | |
| t = v[2]; /* nonzero, by definition */ | |
| q1 = u[1] / t; | |
| rbj = COMBINE(u[1] % t, u[2]); | |
| q2 = rbj / t; | |
| rbj = COMBINE(rbj % t, u[3]); | |
| q3 = rbj / t; | |
| rbj = COMBINE(rbj % t, u[4]); | |
| q4 = rbj / t; | |
| if (arq) | |
| *arq = rbj % t; | |
| tmp.ul[H] = COMBINE(q1, q2); | |
| tmp.ul[L] = COMBINE(q3, q4); | |
| return (tmp.q); | |
| } | |
| } | |
| /* | |
| * By adjusting q once we determine m, we can guarantee that | |
| * there is a complete four-digit quotient at &qspace[1] when | |
| * we finally stop. | |
| */ | |
| for (m = 4 - n; u[1] == 0; u++) | |
| m--; | |
| for (i = 4 - m; --i >= 0;) | |
| q[i] = 0; | |
| q += 4 - m; | |
| /* | |
| * Here we run Program D, translated from MIX to C and acquiring | |
| * a few minor changes. | |
| * | |
| * D1: choose multiplier 1 << d to ensure v[1] >= B/2. | |
| */ | |
| d = 0; | |
| for (t = v[1]; t < B / 2; t <<= 1) | |
| d++; | |
| if (d > 0) { | |
| __shl(&u[0], m + n, d); /* u <<= d */ | |
| __shl(&v[1], n - 1, d); /* v <<= d */ | |
| } | |
| /* | |
| * D2: j = 0. | |
| */ | |
| j = 0; | |
| v1 = v[1]; /* for D3 -- note that v[1..n] are constant */ | |
| v2 = v[2]; /* for D3 */ | |
| do { | |
| register digit uj0, uj1, uj2; | |
| /* | |
| * D3: Calculate qhat (\^q, in TeX notation). | |
| * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and | |
| * let rhat = (u[j]*B + u[j+1]) mod v[1]. | |
| * While rhat < B and v[2]*qhat > rhat*B+u[j+2], | |
| * decrement qhat and increase rhat correspondingly. | |
| * Note that if rhat >= B, v[2]*qhat < rhat*B. | |
| */ | |
| uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */ | |
| uj1 = u[j + 1]; /* for D3 only */ | |
| uj2 = u[j + 2]; /* for D3 only */ | |
| if (uj0 == v1) { | |
| qhat = B; | |
| rhat = uj1; | |
| goto qhat_too_big; | |
| } else { | |
| u_long nn = COMBINE(uj0, uj1); | |
| qhat = nn / v1; | |
| rhat = nn % v1; | |
| } | |
| while (v2 * qhat > COMBINE(rhat, uj2)) { | |
| qhat_too_big: | |
| qhat--; | |
| if ((rhat += v1) >= B) | |
| break; | |
| } | |
| /* | |
| * D4: Multiply and subtract. | |
| * The variable `t' holds any borrows across the loop. | |
| * We split this up so that we do not require v[0] = 0, | |
| * and to eliminate a final special case. | |
| */ | |
| for (t = 0, i = n; i > 0; i--) { | |
| t = u[i + j] - v[i] * qhat - t; | |
| u[i + j] = LHALF(t); | |
| t = (B - HHALF(t)) & (B - 1); | |
| } | |
| t = u[j] - t; | |
| u[j] = LHALF(t); | |
| /* | |
| * D5: test remainder. | |
| * There is a borrow if and only if HHALF(t) is nonzero; | |
| * in that (rare) case, qhat was too large (by exactly 1). | |
| * Fix it by adding v[1..n] to u[j..j+n]. | |
| */ | |
| if (HHALF(t)) { | |
| qhat--; | |
| for (t = 0, i = n; i > 0; i--) { /* D6: add back. */ | |
| t += u[i + j] + v[i]; | |
| u[i + j] = LHALF(t); | |
| t = HHALF(t); | |
| } | |
| u[j] = LHALF(u[j] + t); | |
| } | |
| q[j] = qhat; | |
| } while (++j <= m); /* D7: loop on j. */ | |
| /* | |
| * If caller wants the remainder, we have to calculate it as | |
| * u[m..m+n] >> d (this is at most n digits and thus fits in | |
| * u[m+1..m+n], but we may need more source digits). | |
| */ | |
| if (arq) { | |
| if (d) { | |
| for (i = m + n; i > m; --i) | |
| u[i] = (u[i] >> d) | | |
| LHALF(u[i - 1] << (HALF_BITS - d)); | |
| u[i] = 0; | |
| } | |
| tmp.ul[H] = COMBINE(uspace[1], uspace[2]); | |
| tmp.ul[L] = COMBINE(uspace[3], uspace[4]); | |
| *arq = tmp.q; | |
| } | |
| tmp.ul[H] = COMBINE(qspace[1], qspace[2]); | |
| tmp.ul[L] = COMBINE(qspace[3], qspace[4]); | |
| return (tmp.q); | |
| } | |
| /* | |
| * Return 0, 1, or 2 as a <, =, > b respectively. | |
| * Neither a nor b are considered signed. | |
| */ | |
| int | |
| __ucmpdi2(u_quad_t a, u_quad_t b) | |
| { | |
| union uu aa, bb; | |
| aa.uq = a; | |
| bb.uq = b; | |
| return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 : | |
| aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1); | |
| } | |
| /* | |
| * Divide two unsigned quads. | |
| */ | |
| u_quad_t | |
| __udivdi3(u_quad_t a, u_quad_t b) | |
| { | |
| return (__qdivrem(a, b, (u_quad_t *)0)); | |
| } | |
| /* | |
| * Return remainder after dividing two unsigned quads. | |
| */ | |
| u_quad_t | |
| __umoddi3(u_quad_t a, u_quad_t b) | |
| { | |
| u_quad_t r; | |
| (void)__qdivrem(a, b, &r); | |
| return (r); | |
| } | |
| /* | |
| * Divide two signed quads. | |
| * This function is new in GCC 7. | |
| */ | |
| quad_t | |
| __divmoddi4(quad_t a, quad_t b, quad_t *rem) | |
| { | |
| u_quad_t ua, ub, uq, ur; | |
| int negq, negr; | |
| if (a < 0) | |
| ua = -(u_quad_t)a, negq = 1, negr = 1; | |
| else | |
| ua = a, negq = 0, negr = 0; | |
| if (b < 0) | |
| ub = -(u_quad_t)b, negq ^= 1; | |
| else | |
| ub = b; | |
| uq = __qdivrem(ua, ub, &ur); | |
| if (rem) | |
| *rem = (negr ? -ur : ur); | |
| return (negq ? -uq : uq); | |
| } | |
| u_quad_t | |
| __udivmoddi4(u_quad_t a, u_quad_t b, u_quad_t *rem) | |
| { | |
| return __qdivrem(a, b, rem); | |
| } | |
| #else | |
| static int __attribute__((unused)) dummy; | |
| #endif /*deined (_X86_) && !defined (__x86_64__)*/ | |