diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-04-27 17:46:48 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-04-27 17:46:48 +0000 |
commit | 4d4116761958b945bbc20fb5a5495c1cc7a897c0 (patch) | |
tree | 177e88316908c6c765dd3bde9ab4ac7cfb5a73b7 | |
parent | 3fd98b3b1027bc45b04855550bc44e05c0a9e95d (diff) |
A quad is two ints, not two longs. Also fix some problems with
conversions from floating point to quad. Problem reported by Marcus
Holland-Moritz. From NetBSD.
ok millert@
-rw-r--r-- | lib/libc/quad/TESTS/divrem.c | 14 | ||||
-rw-r--r-- | lib/libc/quad/TESTS/mul.c | 12 | ||||
-rw-r--r-- | lib/libc/quad/adddi3.c | 4 | ||||
-rw-r--r-- | lib/libc/quad/ashldi3.c | 13 | ||||
-rw-r--r-- | lib/libc/quad/ashrdi3.c | 22 | ||||
-rw-r--r-- | lib/libc/quad/divdi3.c | 20 | ||||
-rw-r--r-- | lib/libc/quad/fixsfdi.c | 5 | ||||
-rw-r--r-- | lib/libc/quad/fixunsdfdi.c | 38 | ||||
-rw-r--r-- | lib/libc/quad/fixunssfdi.c | 18 | ||||
-rw-r--r-- | lib/libc/quad/floatdidf.c | 6 | ||||
-rw-r--r-- | lib/libc/quad/floatdisf.c | 6 | ||||
-rw-r--r-- | lib/libc/quad/floatunsdidf.c | 4 | ||||
-rw-r--r-- | lib/libc/quad/lshldi3.c | 13 | ||||
-rw-r--r-- | lib/libc/quad/lshrdi3.c | 13 | ||||
-rw-r--r-- | lib/libc/quad/moddi3.c | 22 | ||||
-rw-r--r-- | lib/libc/quad/muldi3.c | 38 | ||||
-rw-r--r-- | lib/libc/quad/qdivrem.c | 75 | ||||
-rw-r--r-- | lib/libc/quad/quad.h | 63 | ||||
-rw-r--r-- | lib/libc/quad/subdi3.c | 4 |
19 files changed, 206 insertions, 184 deletions
diff --git a/lib/libc/quad/TESTS/divrem.c b/lib/libc/quad/TESTS/divrem.c index 4254f7c4a10..394793545f9 100644 --- a/lib/libc/quad/TESTS/divrem.c +++ b/lib/libc/quad/TESTS/divrem.c @@ -38,14 +38,14 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char rcsid[] = "$OpenBSD: divrem.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: divrem.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* not lint */ #include <stdio.h> main() { - union { long long q; unsigned long v[2]; } a, b, q, r; + union { long long q; unsigned int v[2]; } a, b, q, r; char buf[300]; extern long long __qdivrem(unsigned long long, unsigned long long, unsigned long long *); @@ -54,19 +54,19 @@ main() printf("> "); if (fgets(buf, sizeof buf, stdin) == NULL) break; - if (sscanf(buf, "%lu:%lu %lu:%lu", + if (sscanf(buf, "%u:%u %u:%u", &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && - sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + sscanf(buf, "0x%x:%x 0x%x:%x", &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { printf("eh?\n"); continue; } q.q = __qdivrem(a.q, b.q, &r.q); - printf("%lx:%lx /%% %lx:%lx => q=%lx:%lx r=%lx:%lx\n", + printf("%x:%x /%% %x:%x => q=%x:%x r=%x:%x\n", a.v[0], a.v[1], b.v[0], b.v[1], q.v[0], q.v[1], r.v[0], r.v[1]); - printf(" = %lX%08lX / %lX%08lX => %lX%08lX\n\ - = %lX%08lX %% %lX%08lX => %lX%08lX\n", + printf(" = %X%08X / %X%08X => %X%08X\n\ + = %X%08X %% %X%08X => %X%08X\n", a.v[0], a.v[1], b.v[0], b.v[1], q.v[0], q.v[1], a.v[0], a.v[1], b.v[0], b.v[1], r.v[0], r.v[1]); } diff --git a/lib/libc/quad/TESTS/mul.c b/lib/libc/quad/TESTS/mul.c index 63282435219..bd5e562b42e 100644 --- a/lib/libc/quad/TESTS/mul.c +++ b/lib/libc/quad/TESTS/mul.c @@ -38,14 +38,14 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char rcsid[] = "$OpenBSD: mul.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: mul.c,v 1.4 2004/04/27 17:46:47 otto Exp $"; #endif /* not lint */ #include <stdio.h> main() { - union { long long q; unsigned long v[2]; } a, b, m; + union { long long q; unsigned int v[2]; } a, b, m; char buf[300]; extern long long __muldi3(long long, long long); @@ -53,17 +53,17 @@ main() printf("> "); if (fgets(buf, sizeof buf, stdin) == NULL) break; - if (sscanf(buf, "%lu:%lu %lu:%lu", + if (sscanf(buf, "%u:%u %u:%u", &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && - sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + sscanf(buf, "0x%x:%x 0x%x:%x", &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { printf("eh?\n"); continue; } m.q = __muldi3(a.q, b.q); - printf("%lx:%lx * %lx:%lx => %lx:%lx\n", + printf("%x:%x * %x:%x => %x:%x\n", a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); - printf(" = %lX%08lX * %lX%08lX => %lX%08lX\n", + printf(" = %X%08X * %X%08X => %X%08X\n", a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); } exit(0); diff --git a/lib/libc/quad/adddi3.c b/lib/libc/quad/adddi3.c index 9649816ec9c..31f0efdb877 100644 --- a/lib/libc/quad/adddi3.c +++ b/lib/libc/quad/adddi3.c @@ -32,14 +32,14 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: adddi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: adddi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" /* * Add two quads. This is trivial since a one-bit carry from a single - * u_long addition x+y occurs if and only if the sum x+y is less than + * u_int addition x+y occurs if and only if the sum x+y is less than * either x or y (the choice to compare with x or y is arbitrary). */ quad_t diff --git a/lib/libc/quad/ashldi3.c b/lib/libc/quad/ashldi3.c index efea0f35ba7..8a1335a35a0 100644 --- a/lib/libc/quad/ashldi3.c +++ b/lib/libc/quad/ashldi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: ashldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: ashldi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -48,14 +48,15 @@ __ashldi3(a, shift) { union uu aa; + if (shift == 0) + return(a); aa.q = a; - if (shift >= LONG_BITS) { - aa.ul[H] = shift >= QUAD_BITS ? 0 : - aa.ul[L] << (shift - LONG_BITS); + if (shift >= INT_BITS) { + aa.ul[H] = aa.ul[L] << (shift - INT_BITS); aa.ul[L] = 0; - } else if (shift > 0) { + } else { aa.ul[H] = (aa.ul[H] << shift) | - (aa.ul[L] >> (LONG_BITS - shift)); + (aa.ul[L] >> (INT_BITS - shift)); aa.ul[L] <<= shift; } return (aa.q); diff --git a/lib/libc/quad/ashrdi3.c b/lib/libc/quad/ashrdi3.c index 4c538252c2b..9b8c0ab5ee0 100644 --- a/lib/libc/quad/ashrdi3.c +++ b/lib/libc/quad/ashrdi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: ashrdi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: ashrdi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -47,24 +47,28 @@ __ashrdi3(a, shift) { union uu aa; + if (shift == 0) + return(a); aa.q = a; - if (shift >= LONG_BITS) { - long s; + if (shift >= INT_BITS) { + int 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), + * INT_BITS is undefined, so we shift (INT_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); + /* LINTED inherits machine dependency */ + s = (aa.sl[H] >> (INT_BITS - 1)) >> 1; + /* LINTED inherits machine dependency*/ + aa.ul[L] = aa.sl[H] >> (shift - INT_BITS); aa.ul[H] = s; - } else if (shift > 0) { + } else { aa.ul[L] = (aa.ul[L] >> shift) | - (aa.ul[H] << (LONG_BITS - shift)); + (aa.ul[H] << (INT_BITS - shift)); + /* LINTED inherits machine dependency */ aa.sl[H] >>= shift; } return (aa.q); diff --git a/lib/libc/quad/divdi3.c b/lib/libc/quad/divdi3.c index 99041e67f3f..b8b5eba4733 100644 --- a/lib/libc/quad/divdi3.c +++ b/lib/libc/quad/divdi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: divdi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: divdi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -46,16 +46,18 @@ __divdi3(a, b) quad_t a, b; { u_quad_t ua, ub, uq; - int neg; + int neg = 0; + + ua = a; + ub = b; if (a < 0) - ua = -(u_quad_t)a, neg = 1; - else - ua = a, neg = 0; + ua = -ua, neg ^= 1; if (b < 0) - ub = -(u_quad_t)b, neg ^= 1; - else - ub = b; + ub = -ub, neg ^= 1; + uq = __qdivrem(ua, ub, (u_quad_t *)0); - return (neg ? -uq : uq); + if (neg) + uq = - uq; + return uq; } diff --git a/lib/libc/quad/fixsfdi.c b/lib/libc/quad/fixsfdi.c index 4f1d3d83a21..502a3d7235b 100644 --- a/lib/libc/quad/fixsfdi.c +++ b/lib/libc/quad/fixsfdi.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: fixsfdi.c,v 1.4 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: fixsfdi.c,v 1.5 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -43,8 +43,7 @@ static char rcsid[] = "$OpenBSD: fixsfdi.c,v 1.4 2003/06/02 20:18:36 millert Exp * * N.B.: must use new ANSI syntax (sorry). */ -/* LONGLONG */ -long long +quad_t __fixsfdi(float x) { if (x < 0) diff --git a/lib/libc/quad/fixunsdfdi.c b/lib/libc/quad/fixunsdfdi.c index 9eb5e8f2e66..7f1e093f9c8 100644 --- a/lib/libc/quad/fixunsdfdi.c +++ b/lib/libc/quad/fixunsdfdi.c @@ -32,12 +32,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: fixunsdfdi.c,v 1.4 2004/04/25 21:05:01 dhartmei Exp $"; +static char rcsid[] = "$OpenBSD: fixunsdfdi.c,v 1.5 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" -#define ONE_FOURTH ((long)1 << (LONG_BITS - 2)) +#define ONE_FOURTH ((int)1 << (INT_BITS - 2)) #define ONE_HALF (ONE_FOURTH * 2.0) #define ONE (ONE_FOURTH * 4.0) @@ -50,8 +50,8 @@ u_quad_t __fixunsdfdi(x) double x; { - double toppart; union uu t; + unsigned int tmp; if (x < 0) return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */ @@ -63,30 +63,14 @@ __fixunsdfdi(x) return (UQUAD_MAX); #endif /* - * Get the upper part of the result. Note that the divide - * may round up; we want to avoid this if possible, so we - * subtract `1/2' first. + * Now we know that 0 <= x <= 18446744073709549568. The upper + * limit is one ulp less than 18446744073709551615 tested for above. + * Dividing this by 2^32 will *not* round irrespective of any + * rounding modes (except if the result is an IEEE denorm). + * Furthermore, the quotient will fit into a 32-bit integer. */ - toppart = (x - ONE_HALF) / ONE; - /* - * Now build a u_quad_t out of the top part. The difference - * between x and this is the bottom part (this may introduce - * a few fuzzy bits, but what the heck). With any luck this - * difference will be nonnegative: x should wind up in the - * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN.. - * 2*ULONG_MAX] instead. - */ - t.ul[H] = (unsigned long)toppart; - t.ul[L] = 0; - x -= (double)t.uq; - if (x < 0) { - t.ul[H]--; - x += ULONG_MAX + 1; - } - if (x > ULONG_MAX) { - t.ul[H]++; - x -= ULONG_MAX + 1; - } - t.ul[L] = (u_long)x; + tmp = x / ONE; + t.ul[L] = (unsigned int) (x - tmp * ONE); + t.ul[H] = tmp; return (t.uq); } diff --git a/lib/libc/quad/fixunssfdi.c b/lib/libc/quad/fixunssfdi.c index 2d4b2536639..6ca9172aab1 100644 --- a/lib/libc/quad/fixunssfdi.c +++ b/lib/libc/quad/fixunssfdi.c @@ -32,12 +32,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: fixunssfdi.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: fixunssfdi.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" -#define ONE_FOURTH ((long)1 << (LONG_BITS - 2)) +#define ONE_FOURTH ((int)1 << (INT_BITS - 2)) #define ONE_HALF (ONE_FOURTH * 2.0) #define ONE (ONE_FOURTH * 4.0) @@ -77,20 +77,20 @@ __fixunssfdi(float f) * between x and this is the bottom part (this may introduce * a few fuzzy bits, but what the heck). With any luck this * difference will be nonnegative: x should wind up in the - * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN.. - * 2*ULONG_MAX] instead. + * range [0..UINT_MAX]. For paranoia, we assume [INT_MIN.. + * 2*UINT_MAX] instead. */ - t.ul[H] = (unsigned long)toppart; + t.ul[H] = (unsigned int)toppart; t.ul[L] = 0; x -= (double)t.uq; if (x < 0) { t.ul[H]--; - x += ULONG_MAX; + x += UINT_MAX; } - if (x > ULONG_MAX) { + if (x > UINT_MAX) { t.ul[H]++; - x -= ULONG_MAX; + x -= UINT_MAX; } - t.ul[L] = (u_long)x; + t.ul[L] = (u_int)x; return (t.uq); } diff --git a/lib/libc/quad/floatdidf.c b/lib/libc/quad/floatdidf.c index 1b6a28fae9b..391de2b42ef 100644 --- a/lib/libc/quad/floatdidf.c +++ b/lib/libc/quad/floatdidf.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: floatdidf.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: floatdidf.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -58,12 +58,12 @@ __floatdidf(x) /* * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L] - * has the units. Ideally we could just set d, add LONG_BITS to + * has the units. Ideally we could just set d, add INT_BITS to * its exponent, and then add the units, but this is portable * code and does not know how to get at an exponent. Machine- * specific code may be able to do this more efficiently. */ - d = (double)u.ul[H] * (((long)1 << (LONG_BITS - 2)) * 4.0); + d = (double)u.ul[H] * (((int)1 << (INT_BITS - 2)) * 4.0); d += u.ul[L]; return (neg ? -d : d); diff --git a/lib/libc/quad/floatdisf.c b/lib/libc/quad/floatdisf.c index 424e752d2cd..441d72a90c1 100644 --- a/lib/libc/quad/floatdisf.c +++ b/lib/libc/quad/floatdisf.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: floatdisf.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: floatdisf.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -58,14 +58,14 @@ __floatdisf(x) /* * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L] - * has the units. Ideally we could just set f, add LONG_BITS to + * has the units. Ideally we could just set f, add INT_BITS to * its exponent, and then add the units, but this is portable * code and does not know how to get at an exponent. Machine- * specific code may be able to do this more efficiently. * * Using double here may be excessive paranoia. */ - f = (double)u.ul[H] * (((long)1 << (LONG_BITS - 2)) * 4.0); + f = (double)u.ul[H] * (((int)1 << (INT_BITS - 2)) * 4.0); f += u.ul[L]; return (neg ? -f : f); diff --git a/lib/libc/quad/floatunsdidf.c b/lib/libc/quad/floatunsdidf.c index c7ce30774f5..37028adbbf0 100644 --- a/lib/libc/quad/floatunsdidf.c +++ b/lib/libc/quad/floatunsdidf.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: floatunsdidf.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: floatunsdidf.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -49,7 +49,7 @@ __floatunsdidf(x) union uu u; u.uq = x; - d = (double)u.ul[H] * (((long)1 << (LONG_BITS - 2)) * 4.0); + d = (double)u.ul[H] * (((int)1 << (INT_BITS - 2)) * 4.0); d += u.ul[L]; return (d); } diff --git a/lib/libc/quad/lshldi3.c b/lib/libc/quad/lshldi3.c index 004ed3375ab..5fcde989367 100644 --- a/lib/libc/quad/lshldi3.c +++ b/lib/libc/quad/lshldi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: lshldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: lshldi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -48,14 +48,15 @@ __lshldi3(a, shift) { union uu aa; + if (shift == 0) + return(a); aa.q = a; - if (shift >= LONG_BITS) { - aa.ul[H] = shift >= QUAD_BITS ? 0 : - aa.ul[L] << (shift - LONG_BITS); + if (shift >= INT_BITS) { + aa.ul[H] = aa.ul[L] << (shift - INT_BITS); aa.ul[L] = 0; - } else if (shift > 0) { + } else { aa.ul[H] = (aa.ul[H] << shift) | - (aa.ul[L] >> (LONG_BITS - shift)); + (aa.ul[L] >> (INT_BITS - shift)); aa.ul[L] <<= shift; } return (aa.q); diff --git a/lib/libc/quad/lshrdi3.c b/lib/libc/quad/lshrdi3.c index 5fe7fba6b35..0df0304baf6 100644 --- a/lib/libc/quad/lshrdi3.c +++ b/lib/libc/quad/lshrdi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: lshrdi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: lshrdi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -47,14 +47,15 @@ __lshrdi3(a, shift) { union uu aa; + if (shift == 0) + return(a); aa.q = a; - if (shift >= LONG_BITS) { - aa.ul[L] = shift >= QUAD_BITS ? 0 : - aa.ul[H] >> (shift - LONG_BITS); + if (shift >= INT_BITS) { + aa.ul[L] = aa.ul[H] >> (shift - INT_BITS); aa.ul[H] = 0; - } else if (shift > 0) { + } else { aa.ul[L] = (aa.ul[L] >> shift) | - (aa.ul[H] << (LONG_BITS - shift)); + (aa.ul[H] << (INT_BITS - shift)); aa.ul[H] >>= shift; } return (aa.q); diff --git a/lib/libc/quad/moddi3.c b/lib/libc/quad/moddi3.c index f166feca3b7..0d4517766ab 100644 --- a/lib/libc/quad/moddi3.c +++ b/lib/libc/quad/moddi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: moddi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: moddi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -40,24 +40,24 @@ static char rcsid[] = "$OpenBSD: moddi3.c,v 1.3 2003/06/02 20:18:36 millert Exp /* * Return remainder after dividing two signed quads. * - * XXX - * If -1/2 should produce -1 on this machine, this code is wrong. + * XXX we assume a % b < 0 iff a < 0, but this is actually machine-dependent. */ quad_t __moddi3(a, b) quad_t a, b; { u_quad_t ua, ub, ur; - int neg; + int neg = 0; + + ua = a; + ub = b; if (a < 0) - ua = -(u_quad_t)a, neg = 1; - else - ua = a, neg = 0; + ua = -ua, neg ^= 1; if (b < 0) - ub = -(u_quad_t)b, neg ^= 1; - else - ub = b; + ub = -ub; (void)__qdivrem(ua, ub, &ur); - return (neg ? -ur : ur); + if (neg) + ur = -ur; + return (ur); } diff --git a/lib/libc/quad/muldi3.c b/lib/libc/quad/muldi3.c index 1e1692ce1f1..d056e40f84a 100644 --- a/lib/libc/quad/muldi3.c +++ b/lib/libc/quad/muldi3.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: muldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: muldi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" @@ -43,7 +43,7 @@ static char rcsid[] = "$OpenBSD: muldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp * Our algorithm is based on the following. Split incoming quad values * u and v (where u,v >= 0) into * - * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32) + * u = 2^n u1 * u0 (n = number of bits in `u_int', usu. 32) * * and * @@ -74,9 +74,9 @@ static char rcsid[] = "$OpenBSD: muldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp * * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278. * - * Since C does not give us a `long * long = quad' operator, we split - * our input quads into two longs, then split the two longs into two - * shorts. We can then calculate `short * short = long' in native + * Since C does not give us a `int * int = quad' operator, we split + * our input quads into two ints, then split the two ints into two + * shorts. We can then calculate `short * short = int' in native * arithmetic. * * Our product should, strictly speaking, be a `long quad', with 128 @@ -94,15 +94,15 @@ static char rcsid[] = "$OpenBSD: muldi3.c,v 1.3 2003/06/02 20:18:36 millert Exp * of 2^n in either one will also vanish. Only `low' need be computed * mod 2^2n, and only because of the final term above. */ -static quad_t __lmulq(u_long, u_long); +static quad_t __lmulq(u_int, u_int); quad_t __muldi3(a, b) quad_t a, b; { union uu u, v, low, prod; - register u_long high, mid, udiff, vdiff; - register int negall, negmid; + u_int high, mid, udiff, vdiff; + int negall, negmid; #define u1 u.ul[H] #define u0 u.ul[L] #define v1 v.ul[H] @@ -111,7 +111,7 @@ __muldi3(a, b) /* * Get u and v such that u, v >= 0. When this is finished, * u1, u0, v1, and v0 will be directly accessible through the - * longword fields. + * int fields. */ if (a >= 0) u.q = a, negall = 0; @@ -134,7 +134,7 @@ __muldi3(a, b) * Compute the three intermediate products, remembering * whether the middle term is negative. We can discard * any upper bits in high and mid, so we can use native - * u_long * u_long => u_long arithmetic. + * u_int * u_int => u_int arithmetic. */ low.q = __lmulq(u0, v0); @@ -165,27 +165,27 @@ __muldi3(a, b) } /* - * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half - * the number of bits in a long (whatever that is---the code below + * Multiply two 2N-bit ints to produce a 4N-bit quad, where N is half + * the number of bits in an int (whatever that is---the code below * does not care as long as quad.h does its part of the bargain---but * typically N==16). * * We use the same algorithm from Knuth, but this time the modulo refinement - * does not apply. On the other hand, since N is half the size of a long, + * does not apply. On the other hand, since N is half the size of an int, * we can get away with native multiplication---none of our input terms - * exceeds (ULONG_MAX >> 1). + * exceeds (UINT_MAX >> 1). * - * Note that, for u_long l, the quad-precision result + * Note that, for u_int l, the quad-precision result * * l << N * - * splits into high and low longs as HHALF(l) and LHUP(l) respectively. + * splits into high and low ints as HHALF(l) and LHUP(l) respectively. */ static quad_t -__lmulq(u_long u, u_long v) +__lmulq(u_int u, u_int v) { - u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low; - u_long prodh, prodl, was; + u_int u1, u0, v1, v0, udiff, vdiff, high, mid, low; + u_int prodh, prodl, was; union uu prod; int neg; diff --git a/lib/libc/quad/qdivrem.c b/lib/libc/quad/qdivrem.c index 6c9e522b2a7..ac666c25707 100644 --- a/lib/libc/quad/qdivrem.c +++ b/lib/libc/quad/qdivrem.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: qdivrem.c,v 1.4 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: qdivrem.c,v 1.5 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -42,25 +42,25 @@ static char rcsid[] = "$OpenBSD: qdivrem.c,v 1.4 2003/06/02 20:18:36 millert Exp #include "quad.h" -#define B ((long)1 << HALF_BITS) /* digit base */ +#define B ((int)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)) +#define COMBINE(a, b) (((u_int)(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 +#if UINT_MAX == 0xffffffffU && USHRT_MAX >= 0xffff typedef unsigned short digit; #else -typedef u_long digit; +typedef u_int digit; #endif -static void shl(digit *p, int len, int sh); +static void shl __P((digit *p, int len, int 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 + * fit within u_int. As a consequence, the maximum length dividend and * divisor are 4 `digits' in this base (they are shorter if they have * leading zeros). */ @@ -70,8 +70,8 @@ __qdivrem(uq, vq, arq) { union uu tmp; digit *u, *v, *q; - register digit v1, v2; - u_long qhat, rhat, t; + digit v1, v2; + u_int qhat, rhat, t; int m, n, d, j, i; digit uspace[5], vspace[5], qspace[5]; @@ -111,18 +111,18 @@ __qdivrem(uq, vq, arq) */ 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]); + u[1] = (digit)HHALF(tmp.ul[H]); + u[2] = (digit)LHALF(tmp.ul[H]); + u[3] = (digit)HHALF(tmp.ul[L]); + u[4] = (digit)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]); + v[1] = (digit)HHALF(tmp.ul[H]); + v[2] = (digit)LHALF(tmp.ul[H]); + v[3] = (digit)HHALF(tmp.ul[L]); + v[4] = (digit)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) */ + u_int rbj; /* r*B+u[j] (not root boy jim) */ digit q1, q2, q3, q4; /* @@ -134,13 +134,13 @@ __qdivrem(uq, vq, arq) * We unroll this completely here. */ t = v[2]; /* nonzero, by definition */ - q1 = u[1] / t; + q1 = (digit)(u[1] / t); rbj = COMBINE(u[1] % t, u[2]); - q2 = rbj / t; + q2 = (digit)(rbj / t); rbj = COMBINE(rbj % t, u[3]); - q3 = rbj / t; + q3 = (digit)(rbj / t); rbj = COMBINE(rbj % t, u[4]); - q4 = rbj / t; + q4 = (digit)(rbj / t); if (arq) *arq = rbj % t; tmp.ul[H] = COMBINE(q1, q2); @@ -180,7 +180,7 @@ __qdivrem(uq, vq, arq) v1 = v[1]; /* for D3 -- note that v[1..n] are constant */ v2 = v[2]; /* for D3 */ do { - register digit uj0, uj1, uj2; + digit uj0, uj1, uj2; /* * D3: Calculate qhat (\^q, in TeX notation). @@ -198,9 +198,9 @@ __qdivrem(uq, vq, arq) rhat = uj1; goto qhat_too_big; } else { - u_long n = COMBINE(uj0, uj1); - qhat = n / v1; - rhat = n % v1; + u_int nn = COMBINE(uj0, uj1); + qhat = nn / v1; + rhat = nn % v1; } while (v2 * qhat > COMBINE(rhat, uj2)) { qhat_too_big: @@ -216,11 +216,11 @@ __qdivrem(uq, vq, arq) */ for (t = 0, i = n; i > 0; i--) { t = u[i + j] - v[i] * qhat - t; - u[i + j] = LHALF(t); + u[i + j] = (digit)LHALF(t); t = (B - HHALF(t)) & (B - 1); } t = u[j] - t; - u[j] = LHALF(t); + u[j] = (digit)LHALF(t); /* * D5: test remainder. * There is a borrow if and only if HHALF(t) is nonzero; @@ -231,12 +231,12 @@ __qdivrem(uq, vq, arq) qhat--; for (t = 0, i = n; i > 0; i--) { /* D6: add back. */ t += u[i + j] + v[i]; - u[i + j] = LHALF(t); + u[i + j] = (digit)LHALF(t); t = HHALF(t); } - u[j] = LHALF(u[j] + t); + u[j] = (digit)LHALF(u[j] + t); } - q[j] = qhat; + q[j] = (digit)qhat; } while (++j <= m); /* D7: loop on j. */ /* @@ -247,8 +247,8 @@ __qdivrem(uq, vq, arq) 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] = (digit)(((u_int)u[i] >> d) | + LHALF((u_int)u[i - 1] << (HALF_BITS - d))); u[i] = 0; } tmp.ul[H] = COMBINE(uspace[1], uspace[2]); @@ -267,11 +267,12 @@ __qdivrem(uq, vq, arq) * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS. */ static void -shl(register digit *p, register int len, register int sh) +shl(digit *p, int len, int sh) { - register int i; + 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); + p[i] = (digit)(LHALF((u_int)p[i] << sh) | + ((u_int)p[i + 1] >> (HALF_BITS - sh))); + p[i] = (digit)(LHALF((u_int)p[i] << sh)); } diff --git a/lib/libc/quad/quad.h b/lib/libc/quad/quad.h index 59a1829fde1..49d20cf4889 100644 --- a/lib/libc/quad/quad.h +++ b/lib/libc/quad/quad.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: quad.h,v 1.4 2003/06/02 20:18:36 millert Exp $ + * $OpenBSD: quad.h,v 1.5 2004/04/27 17:46:46 otto Exp $ */ /* @@ -40,17 +40,21 @@ * * - The type long long (aka quad_t) exists. * - * - A quad variable is exactly twice as long as `long'. + * - A quad variable is exactly twice as long as `int'. * * - 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. + * quads and 64-bit ints, for instance, or 96-bit arithmetic on machines + * with 48-bit ints. */ #include <sys/types.h> +#if !defined(_KERNEL) && !defined(_STANDALONE) #include <limits.h> +#else +#include <machine/limits.h> +#endif /* * Depending on the desired operation, we view a `long long' (aka quad_t) in @@ -59,12 +63,12 @@ union uu { quad_t q; /* as a (signed) quad */ u_quad_t uq; /* as an unsigned quad */ - long sl[2]; /* as two signed longs */ - u_long ul[2]; /* as two unsigned longs */ + int sl[2]; /* as two signed ints */ + u_int ul[2]; /* as two unsigned ints */ }; /* - * Define high and low longwords. + * Define high and low parts of a quad_t. */ #define H _QUAD_HIGHWORD #define L _QUAD_LOWWORD @@ -75,23 +79,21 @@ union uu { * 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) +#define INT_BITS (sizeof(int) * CHAR_BIT) +#define HALF_BITS (sizeof(int) * 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.) + * ((quad_t)(x) << (number_of_bits_in_int/2)). (`x' must actually be u_int.) * * 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). + * (sizeof(int)*CHAR_BIT/2). */ -#define HHALF(x) ((u_long)(x) >> HALF_BITS) -#define LHALF(x) ((u_long)(x) & (((long)1 << HALF_BITS) - 1)) -#define LHUP(x) ((u_long)(x) << HALF_BITS) - -extern u_quad_t __qdivrem(u_quad_t u, u_quad_t v, u_quad_t *rem); +#define HHALF(x) ((u_int)(x) >> HALF_BITS) +#define LHALF(x) ((u_int)(x) & (((int)1 << HALF_BITS) - 1)) +#define LHUP(x) ((u_int)(x) << HALF_BITS) /* * XXX @@ -99,8 +101,35 @@ extern u_quad_t __qdivrem(u_quad_t u, u_quad_t v, u_quad_t *rem); * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use * both compilers. */ -#if __GNUC__ >= 2 +#if __GNUC_PREREQ__(2, 0) || defined(lint) typedef unsigned int qshift_t; #else typedef u_quad_t qshift_t; #endif + +quad_t __adddi3(quad_t, quad_t); +quad_t __anddi3(quad_t, quad_t); +quad_t __ashldi3(quad_t, qshift_t); +quad_t __ashrdi3(quad_t, qshift_t); +int __cmpdi2(quad_t, quad_t); +quad_t __divdi3(quad_t, quad_t); +quad_t __fixdfdi(double); +quad_t __fixsfdi(float); +u_quad_t __fixunsdfdi(double); +u_quad_t __fixunssfdi(float); +double __floatdidf(quad_t); +float __floatdisf(quad_t); +double __floatunsdidf(u_quad_t); +quad_t __iordi3(quad_t, quad_t); +quad_t __lshldi3(quad_t, qshift_t); +quad_t __lshrdi3(quad_t, qshift_t); +quad_t __moddi3(quad_t, quad_t); +quad_t __muldi3(quad_t, quad_t); +quad_t __negdi2(quad_t); +quad_t __one_cmpldi2(quad_t); +u_quad_t __qdivrem(u_quad_t, u_quad_t, u_quad_t *); +quad_t __subdi3(quad_t, quad_t); +int __ucmpdi2(u_quad_t, u_quad_t); +u_quad_t __udivdi3(u_quad_t, u_quad_t ); +u_quad_t __umoddi3(u_quad_t, u_quad_t ); +quad_t __xordi3(quad_t, quad_t); diff --git a/lib/libc/quad/subdi3.c b/lib/libc/quad/subdi3.c index ef82dc66170..7a2ce98344c 100644 --- a/lib/libc/quad/subdi3.c +++ b/lib/libc/quad/subdi3.c @@ -32,14 +32,14 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: subdi3.c,v 1.3 2003/06/02 20:18:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: subdi3.c,v 1.4 2004/04/27 17:46:46 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" /* * Subtract two quad values. This is trivial since a one-bit carry - * from a single u_long difference x-y occurs if and only if (x-y) > x. + * from a single u_int difference x-y occurs if and only if (x-y) > x. */ quad_t __subdi3(a, b) |