summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2004-04-27 17:46:48 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2004-04-27 17:46:48 +0000
commit4d4116761958b945bbc20fb5a5495c1cc7a897c0 (patch)
tree177e88316908c6c765dd3bde9ab4ac7cfb5a73b7
parent3fd98b3b1027bc45b04855550bc44e05c0a9e95d (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.c14
-rw-r--r--lib/libc/quad/TESTS/mul.c12
-rw-r--r--lib/libc/quad/adddi3.c4
-rw-r--r--lib/libc/quad/ashldi3.c13
-rw-r--r--lib/libc/quad/ashrdi3.c22
-rw-r--r--lib/libc/quad/divdi3.c20
-rw-r--r--lib/libc/quad/fixsfdi.c5
-rw-r--r--lib/libc/quad/fixunsdfdi.c38
-rw-r--r--lib/libc/quad/fixunssfdi.c18
-rw-r--r--lib/libc/quad/floatdidf.c6
-rw-r--r--lib/libc/quad/floatdisf.c6
-rw-r--r--lib/libc/quad/floatunsdidf.c4
-rw-r--r--lib/libc/quad/lshldi3.c13
-rw-r--r--lib/libc/quad/lshrdi3.c13
-rw-r--r--lib/libc/quad/moddi3.c22
-rw-r--r--lib/libc/quad/muldi3.c38
-rw-r--r--lib/libc/quad/qdivrem.c75
-rw-r--r--lib/libc/quad/quad.h63
-rw-r--r--lib/libc/quad/subdi3.c4
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)