[Commit] cairo_u128 .cvsignore, NONE, 1.1 Makefile, 1.2, 1.3 cairo_test.c, 1.2, 1.3 cairo_uint128.c, 1.2, 1.3 cairo_uint128.h, 1.2, 1.3 checkdata.5c, 1.2, 1.3

Keith Packard commit at keithp.com
Mon May 24 23:43:14 PDT 2004


Committed by: keithp

Update of /local/src/CVS/cairo_u128
In directory home.keithp.com:/tmp/cvs-serv8206

Modified Files:
	Makefile cairo_test.c cairo_uint128.c cairo_uint128.h 
	checkdata.5c 
Added Files:
	.cvsignore 
Log Message:
2004-05-24  Keith Packard  <keithp at keithp.com>

	* .cvsignore:
	* Makefile:
	* cairo_test.c: (zero_dump_uint64), (dump_uint64), (dump_uint128),
	(main):
	* cairo_uint128.c: (_cairo_uint32_to_uint64), (_cairo_uint64_add),
	(_cairo_uint64_sub), (_cairo_uint32x32_64_mul),
	(_cairo_uint64_mul), (_cairo_uint64_lt), (_cairo_uint64_eq),
	(_cairo_uint32_to_uint128), (_cairo_uint64_to_uint128),
	(_cairo_uint128_add), (_cairo_uint128_sub), (uint64_lo),
	(uint64_hi), (uint64_shift32), (_cairo_uint64x64_128_mul),
	(_cairo_uint128_mul), (_cairo_uint128_lt), (_cairo_uint128_eq):
	* cairo_uint128.h:
	* checkdata.5c:
	Rewrite arithmetic to use larger datatypes.  Simpler code,
	faster execution.  Carries are the only tricky part.


--- NEW FILE: .cvsignore ---
c
cairo_test
data
nickle

Index: Makefile
===================================================================
RCS file: /local/src/CVS/cairo_u128/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/Makefile	25 May 2004 05:04:49 -0000	1.2
+++ b/Makefile	25 May 2004 06:43:12 -0000	1.3
@@ -1,14 +1,16 @@
-WIDTH=4
+WIDTH=8
 SETS=1000
+REPS=1000
+HAVE_UINT64_T=1
 
-CFLAGS=-g -DWIDTH=$(WIDTH)
+CFLAGS=-O4 -DWIDTH=$(WIDTH) -DHAVE_UINT64_T=$(HAVE_UINT64_T)
 OBJS = cairo_uint128.o cairo_test.o
 
 check: c nickle
 	cmp c nickle
 
-c: cairo_test data
-	./cairo_test < data > $@
+c: cairo_test data Makefile
+	./cairo_test $(WIDTH) $(SETS) < data > $@
 
 nickle: checkdata.5c data Makefile
 	./checkdata.5c $(WIDTH) < data > $@
@@ -19,7 +21,10 @@
 cairo_test: $(OBJS)
 	$(CC) $(CFLAGS) -o $@ $(OBJS)
 
-$(OBJS): Makefile cairo_uint128.h
+bench:
+	time ./cairo_test $(WIDTH) $(SETS) $(REPS) < data
+
+$(OBJS): cairo_uint128.h Makefile
 
 clean:
 	rm -f c nickle data cairo_test $(OBJS)

Index: cairo_test.c
===================================================================
RCS file: /local/src/CVS/cairo_u128/cairo_test.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/cairo_test.c	25 May 2004 05:04:49 -0000	1.2
+++ b/cairo_test.c	25 May 2004 06:43:12 -0000	1.3
@@ -24,103 +24,108 @@
 
 #include "cairo_uint128.h"
 #include <stdio.h>
+#include <stdlib.h>
 
+void
+zero_dump_uint64 (cairo_uint64_t q, int zero)
+{
 #if HAVE_UINT64_T
-#define NUM_IN_UINT128	4
-#define WIDE_FORMAT "%08x"
+    printf (zero ? "%016llx" : "%llx", q);
 #else
-#define NUM_IN_UINT64	4
-#define NUM_IN_UINT128	8
-#define WIDE_FORMAT "%04x"
+    if (q.b[1] || zero)
+	printf (zero ? "%08x%08x" : "%x%08x", q.b[1], q.b[0]);
+    else
+	printf ("%x", q.b[0]);
 #endif
+}
 
 void
-dump_uint128 (cairo_uint128_t	q)
+dump_uint64 (cairo_uint64_t q)
 {
-    char    *format = "%x";
-    int	    i;
-    int	    start = 0;
-    
-    for (i = NUM_IN_UINT128 - 1; i >= 0; i--)
-    {
-	if (q.b[i])
-	    start=1;
-	if (start)
-	{
-	    printf (format, q.b[i]);
-	    format = WIDE_FORMAT;
-	}
-    }
+    zero_dump_uint64 (q, 0);
     printf ("\n");
 }
 
 void
-dump_uint64 (cairo_uint64_t	q)
+dump_uint128 (cairo_uint128_t	q)
 {
-#if HAVE_UINT64_T
-    printf ("%llx\n", q);
-#else
-    char    *format = "%x";
-    int	    i;
-    int	    start = 0;
+    int	    zero = 0;
     
-    for (i = NUM_IN_UINT64 - 1; i >= 0; i--)
+    if (_cairo_uint64_ne(q.b[1], _cairo_uint32_to_uint64(0)))
     {
-	if (q.b[i])
-	    start=1;
-	if (start)
-	{
-	    printf (format, q.b[i]);
-	    format = WIDE_FORMAT;
-	}
+	zero_dump_uint64 (q.b[1], 0);
+	zero = 1;
     }
+    zero_dump_uint64 (q.b[0], zero);
     printf ("\n");
-#endif
 }
 
 int
 main (int argc, char **argv)
 {
     unsigned int    i;
-    cairo_uint128_t q[WIDTH], qv;
-    cairo_uint64_t  d[WIDTH], dv;
+    cairo_uint128_t *q, qv;
+    cairo_uint64_t  *d, dv;
     int		    c;
+    int		    width = atoi (argv[1]);
+    int		    sets = atoi (argv[2]);
+    int		    reps = argv[3] ? atoi(argv[3]) : 1;
+    int		    r;
+    int		    s;
 
-    for (;;)
+    q = malloc (width * sets * sizeof (cairo_uint128_t));
+    d = malloc (width * sets * sizeof (cairo_uint64_t));
+    for (s = 0; s < sets; s++)
     {
-	for (c = 0; c < WIDTH; c++)
+	for (c = 0; c < width; c++)
 	{
 	    if (scanf ("%u", &i) != 1)
 		exit (0);
-	    q[c] = _cairo_uint32_to_uint128 (i);
-	    d[c] = _cairo_uint32_to_uint64 (i);
+	    q[c + s*width] = _cairo_uint32_to_uint128 (i);
+	    d[c + s*width] = _cairo_uint32_to_uint64 (i);
 	}
-	qv = _cairo_uint32_to_uint128 (1);
-	dv = _cairo_uint32_to_uint64 (1);
-	for (c = 0; c < WIDTH; c++)
+    }
+    for (r = 0; r < reps; r++)
+    {
+	for (s = 0; s < sets; s++)
 	{
-	    qv = _cairo_uint128_mul (qv, q[c]);
-	    dv = _cairo_uint64_mul (dv, d[c]);
-	}
-	dump_uint128 (qv);
-	dump_uint64 (dv);
+	    qv = _cairo_uint32_to_uint128 (1);
+	    dv = _cairo_uint32_to_uint64 (1);
+	    for (c = 0; c < width; c++)
+	    {
+		qv = _cairo_uint128_mul (qv, q[c + s*width]);
+		dv = _cairo_uint64_mul (dv, d[c + s*width]);
+	    }
+	    if (reps == 1)
+	    {
+		dump_uint128 (qv);
+		dump_uint64 (dv);
+	    }
 
-	for (c = 0; c < WIDTH; c++)
-	{
-	    qv = _cairo_uint128_sub (qv, q[c]);
-	    dv = _cairo_uint64_sub (dv, d[c]);
-	}
-	dump_uint128 (qv);
-	dump_uint64 (dv);
+	    for (c = 0; c < width; c++)
+	    {
+		qv = _cairo_uint128_sub (qv, q[c + s*width]);
+		dv = _cairo_uint64_sub (dv, d[c + s*width]);
+	    }
+	    if (reps == 1)
+	    {
+		dump_uint128 (qv);
+		dump_uint64 (dv);
+	    }
 
-	qv = _cairo_uint32_to_uint128 (0);
-	dv = _cairo_uint32_to_uint64 (0);
-	for (c = 0; c < WIDTH; c++)
-	{
-	    qv = _cairo_uint128_add (qv, q[c]);
-	    dv = _cairo_uint64_add (dv, d[c]);
+	    qv = _cairo_uint32_to_uint128 (0);
+	    dv = _cairo_uint32_to_uint64 (0);
+	    for (c = 0; c < width; c++)
+	    {
+		qv = _cairo_uint128_add (qv, q[c + s*width]);
+		dv = _cairo_uint64_add (dv, d[c + s*width]);
+	    }
+	    if (reps == 1)
+	    {
+		dump_uint128 (qv);
+		dump_uint64 (dv);
+	    }
 	}
-	dump_uint128 (qv);
-	dump_uint64 (dv);
     }
+    return 0;
 }

Index: cairo_uint128.c
===================================================================
RCS file: /local/src/CVS/cairo_u128/cairo_uint128.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/cairo_uint128.c	25 May 2004 05:04:49 -0000	1.2
+++ b/cairo_uint128.c	25 May 2004 06:43:12 -0000	1.3
@@ -37,7 +37,7 @@
 typedef uint16_t    cairo_uint_t;
 typedef uint32_t    cairo_2uint_t;
 #define NUM_IN_UINT128	8
-#define NUM_IN_UINT64	4
+#define NUM_IN_UINT64	CAIRO_NUM_IN_UINT64
 #define BITS_IN_UINT	16
 #define MAX_UINT	0xffff
 
@@ -45,271 +45,242 @@
 
 #if !HAVE_UINT64_T
 
-cairo_uint64_t
+const cairo_uint64_t
 _cairo_uint32_to_uint64 (uint32_t i)
 {
     cairo_uint64_t	q;
 
-    q.b[0] = (uint16_t) i;
-    q.b[1] = (uint16_t) (i >> 16);
-    q.b[2] = 0;
-    q.b[3] = 0;
+    q.b[0] = i;
+    q.b[1] = 0;
     return q;
 }
 
-cairo_uint64_t
+const cairo_uint64_t
 _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b)
 {
     cairo_uint64_t	s;
-    int			i;
-    cairo_2uint_t	t;
-    cairo_uint_t	carry = 0;
 
-    for (i = 0; i < NUM_IN_UINT64; i++)
-    {
-	t = (cairo_2uint_t) a.b[i] + (cairo_2uint_t) b.b[i] + carry;
-	carry = (cairo_uint_t) (t >> BITS_IN_UINT);
-	s.b[i] = (cairo_uint_t) t;
-    }
+    s.b[1] = a.b[1] + b.b[1];
+    s.b[0] = a.b[0] + b.b[0];
+    if (s.b[0] < a.b[0])
+	s.b[1]++;
     return s;
 }
 
-cairo_uint64_t
+const cairo_uint64_t
 _cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b)
 {
     cairo_uint64_t	s;
-    int			i;
-    cairo_2uint_t	t;
-    cairo_uint_t	carry = 0;
 
-    for (i = 0; i < NUM_IN_UINT64; i++)
-    {
-	t = (cairo_2uint_t) a.b[i] - (cairo_2uint_t) b.b[i] - carry;
-	carry = ((cairo_uint_t) (t >> BITS_IN_UINT)) & 1;
-	s.b[i] = (cairo_uint_t) t;
-    }
+    s.b[1] = a.b[1] - b.b[1];
+    s.b[0] = a.b[0] - b.b[0];
+    if (s.b[0] > a.b[0])
+	s.b[1]--;
     return s;
 }
 
-cairo_uint64_t
-_cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b)
+#define uint32_lo(i)	((i) & 0xffff)
+#define uint32_hi(i)	((i) >> 16)
+#define uint32_carry16	((1) << 16)
+
+const cairo_uint64_t
+_cairo_uint32x32_64_mul (uint32_t a, uint32_t b)
 {
-    cairo_uint64_t	s;
-    int			sibase, siloop, si;
-    int			ai, bi;
-    cairo_uint_t	ad;
-    cairo_uint_t	carry;
-    cairo_2uint_t	t;
+    cairo_uint64_t  s;
+    
+    uint16_t	ah, al, bh, bl;
+    uint32_t	r0, r1, r2, r3;
 
-    memset (&s, '\0', sizeof (s));
-    sibase = 0;
-    for (ai = 0; ai < NUM_IN_UINT64; ai++)
-    {
-	carry = 0;
-	siloop = sibase++;
-	ad = a.b[ai];
-	for (bi = 0; bi < NUM_IN_UINT64; bi++)
-	{
-	    t = (cairo_2uint_t) ad * (cairo_2uint_t) b.b[bi] + carry;
-	    carry = (cairo_uint_t) (t >> BITS_IN_UINT);
-	    t = (cairo_2uint_t) (cairo_uint_t) t;
-	    for (si = siloop++; t && si < NUM_IN_UINT64; si++)
-	    {
-		t += (cairo_2uint_t) s.b[si];
-		s.b[si] = (cairo_uint_t) t;
-		t = t >> BITS_IN_UINT;
-	    }
-	}
-    }
+    al = uint32_lo (a);
+    ah = uint32_hi (a);
+    bl = uint32_lo (b);
+    bh = uint32_hi (b);
+
+    r0 = (uint32_t) al * bl;
+    r1 = (uint32_t) al * bh;
+    r2 = (uint32_t) ah * bl;
+    r3 = (uint32_t) ah * bh;
+
+    r1 += uint32_hi(r0);    /* no carry possible */
+    r1 += r2;		    /* but this can carry */
+    if (r1 < r2)	    /* check */
+	r3 += uint32_carry16;
+
+    s.b[1] = r3 + uint32_hi(r1);
+    s.b[0] = (uint32_lo (r1) << 16) + uint32_lo (r0);
     return s;
 }
 
-/*
- * If this appears in profiles as being a performance problem,
- * it can be easily recoded with half as many multiplies
- */
-cairo_uint64_t
-_cairo_uint32x32_64_mul (uint32_t a, uint32_t b)
+const cairo_uint64_t
+_cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b)
 {
-    return _cairo_uint64_mul (_cairo_uint32_to_uint64 (a),
-			       _cairo_uint32_to_uint64 (b));
+    cairo_uint64_t	s;
+    
+    s = _cairo_uint32x32_64_mul (a.b[0], b.b[0]);
+    s.b[1] += a.b[0] * b.b[1] + a.b[1] * b.b[0];
+    return s;
 }
 
-int
+const int
 _cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b)
 {
-    int	    i;
-
-    for (i = NUM_IN_UINT64 - 1; i >= 0; i--)
-    {
-	if (a.b[i] < b.b[i])
-	    return 1;
-	if (a.b[i] > b.b[i])
-	    return 0;
-    }
-    return 0;
+    return (a.b[1] < b.b[1] ||
+	    (a.b[1] == b.b[1] && a.b[0] < b.b[0]));
 }
 
-int
+const int
 _cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b)
 {
-    int	    i;
-
-    for (i = 0; i < NUM_IN_UINT64; i++)
-	if (a.b[i] != b.b[i])
-	    return 0;
-    return 1;
+    return a.b[1] == b.b[1] && a.b[0] == b.b[0];
 }
 
 #endif /* !HAVE_UINT64_T */
 
-cairo_uint128_t
+const cairo_uint128_t
 _cairo_uint32_to_uint128 (uint32_t i)
 {
     cairo_uint128_t	q;
 
-#if HAVE_UINT64_T
-    q.b[0] = i;
-    q.b[1] = 0;
-    q.b[2] = 0;
-    q.b[3] = 0;
-#else
-    q.b[0] = (uint16_t) i;
-    q.b[1] = (uint16_t) (i >> 16);
-    q.b[2] = 0;
-    q.b[3] = 0;
-    q.b[4] = 0;
-    q.b[5] = 0;
-    q.b[6] = 0;
-    q.b[7] = 0;
-#endif
+    q.b[0] = _cairo_uint32_to_uint64 (i);
+    q.b[1] = _cairo_uint32_to_uint64 (0);
     return q;
 }
 
-cairo_uint128_t
+const cairo_uint128_t
 _cairo_uint64_to_uint128 (cairo_uint64_t i)
 {
     cairo_uint128_t	q;
 
-#if HAVE_UINT64_T
     q.b[0] = i;
-    q.b[1] = i >> 32;
-    q.b[2] = 0;
-    q.b[3] = 0;
-#else
-    q.b[0] = i.b[0];
-    q.b[1] = i.b[1];
-    q.b[2] = i.b[2];
-    q.b[3] = i.b[3];
-    q.b[4] = 0;
-    q.b[5] = 0;
-    q.b[6] = 0;
-    q.b[7] = 0;
-#endif
+    q.b[1] = _cairo_uint32_to_uint64 (0);
     return q;
 }
 
-cairo_uint128_t
+const cairo_uint128_t
 _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b)
 {
     cairo_uint128_t	s;
-    int			i;
-    cairo_2uint_t	t;
-    cairo_uint_t	carry = 0;
 
-    for (i = 0; i < NUM_IN_UINT128; i++)
-    {
-	t = (cairo_2uint_t) a.b[i] + (cairo_2uint_t) b.b[i] + carry;
-	carry = (cairo_uint_t) (t >> BITS_IN_UINT);
-	s.b[i] = (cairo_uint_t) t;
-    }
+    s.b[1] = _cairo_uint64_add (a.b[1], b.b[1]);
+    s.b[0] = _cairo_uint64_add (a.b[0], b.b[0]);
+    if (_cairo_uint64_lt (s.b[0], a.b[0]))
+	s.b[1] = _cairo_uint64_add (s.b[1], _cairo_uint32_to_uint64 (1));
     return s;
 }
 
-cairo_uint128_t
+const cairo_uint128_t
 _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b)
 {
     cairo_uint128_t	s;
-    int			i;
-    cairo_2uint_t	t;
-    cairo_uint_t	carry = 0;
 
-    for (i = 0; i < NUM_IN_UINT128; i++)
-    {
-	t = (cairo_2uint_t) a.b[i] - (cairo_2uint_t) b.b[i] - carry;
-	carry = ((cairo_uint_t) (t >> BITS_IN_UINT)) & 1;
-	s.b[i] = (cairo_uint_t) t;
-    }
+    s.b[1] = _cairo_uint64_sub (a.b[1], b.b[1]);
+    s.b[0] = _cairo_uint64_sub (a.b[0], b.b[0]);
+    if (_cairo_uint64_gt (s.b[0], a.b[0]))
+	s.b[1] = _cairo_uint64_sub (s.b[1], _cairo_uint32_to_uint64(1));
     return s;
 }
 
-cairo_uint128_t
-_cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b)
+#if HAVE_UINT64_T
+
+#define uint64_lo32(i)	((i) & 0xffffffff)
+#define uint64_hi32(i)	((i) >> 32)
+#define uint64_lo(i)	((i) & 0xffffffff)
+#define uint64_hi(i)	((i) >> 32)
+#define uint64_shift32(i)   ((i) << 32)
+#define uint64_carry32	(((uint64_t) 1) << 32)
+
+#else
+
+#define uint64_lo32(i)	((i).b[0])
+#define uint64_hi32(i)	((i).b[1])
+
+static const cairo_uint64_t
+uint64_lo (cairo_uint64_t i)
 {
-    cairo_uint128_t	s;
-    int			sibase, siloop, si;
-    int			ai, bi;
-    cairo_uint_t	ad;
-    cairo_uint_t	carry;
-    cairo_2uint_t	t;
+    cairo_uint64_t  s;
 
-    memset (&s, '\0', sizeof (s));
-    sibase = 0;
-    for (ai = 0; ai < NUM_IN_UINT128; ai++)
-    {
-	carry = 0;
-	siloop = sibase++;
-	ad = a.b[ai];
-	for (bi = 0; bi < NUM_IN_UINT128; bi++)
-	{
-	    t = (cairo_2uint_t) ad * (cairo_2uint_t) b.b[bi] + carry;
-	    carry = (cairo_uint_t) (t >> BITS_IN_UINT);
-	    t = (cairo_2uint_t) (cairo_uint_t) t;
-	    for (si = siloop++; t && si < NUM_IN_UINT128; si++)
-	    {
-		t += (cairo_2uint_t) s.b[si];
-		s.b[si] = (cairo_uint_t) t;
-		t = t >> BITS_IN_UINT;
-	    }
-	}
-    }
+    s.b[0] = i.b[0];
+    s.b[1] = 0;
     return s;
 }
 
-/*
- * If this appears in profiles as being a performance problem,
- * it can be easily recoded with half as many multiplies
- */
+static const cairo_uint64_t
+uint64_hi (cairo_uint64_t i)
+{
+    cairo_uint64_t  s;
+
+    s.b[0] = i.b[1];
+    s.b[1] = 0;
+    return s;
+}
+
+static const cairo_uint64_t
+uint64_shift32 (cairo_uint64_t i)
+{
+    cairo_uint64_t  s;
+
+    s.b[0] = 0;
+    s.b[1] = i.b[0];
+    return s;
+}
+
+static const cairo_uint64_t uint64_carry32 = { 0, 1 };
+
+#endif
+
 cairo_uint128_t
 _cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b)
 {
-    return _cairo_uint128_mul (_cairo_uint64_to_uint128 (a),
-			       _cairo_uint64_to_uint128 (b));
+    cairo_uint128_t	s;
+    uint32_t		ah, al, bh, bl;
+    cairo_uint64_t	r0, r1, r2, r3;
+
+    al = uint64_lo32 (a);
+    ah = uint64_hi32 (a);
+    bl = uint64_lo32 (b);
+    bh = uint64_hi32 (b);
+
+    r0 = _cairo_uint32x32_64_mul (al, bl);
+    r1 = _cairo_uint32x32_64_mul (al, bh);
+    r2 = _cairo_uint32x32_64_mul (ah, bl);
+    r3 = _cairo_uint32x32_64_mul (ah, bh);
+
+    r1 = _cairo_uint64_add (r1, uint64_hi (r0));    /* no carry possible */
+    r1 = _cairo_uint64_add (r1, r2);	    	    /* but this can carry */
+    if (_cairo_uint64_lt (r1, r2))		    /* check */
+	r3 = _cairo_uint64_add (r3, uint64_carry32);
+
+    s.b[1] = _cairo_uint64_add (r3, uint64_hi(r1));
+    s.b[0] = _cairo_uint64_add (uint64_shift32 (r1),
+				uint64_lo (r0));
+    return s;
 }
 
-int
-_cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b)
+const cairo_uint128_t
+_cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b)
 {
-    int	    i;
+    cairo_uint128_t	s;
 
-    for (i = NUM_IN_UINT128 - 1; i >= 0; i--)
-    {
-	if (a.b[i] < b.b[i])
-	    return 1;
-	if (a.b[i] > b.b[i])
-	    return 0;
-    }
-    return 0;
+    s = _cairo_uint64x64_128_mul (a.b[0], b.b[0]);
+    s.b[1] = _cairo_uint64_add (s.b[1],
+				_cairo_uint64_mul (a.b[0], b.b[1]));
+    s.b[1] = _cairo_uint64_add (s.b[1],
+				_cairo_uint64_mul (a.b[1], b.b[0]));
+    return s;
 }
 
-int
-_cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b)
+const int
+_cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b)
 {
-    int	    i;
+    return (_cairo_uint64_lt (a.b[1], b.b[1]) ||
+	    (_cairo_uint64_eq (a.b[1], b.b[1]) &&
+	     _cairo_uint64_lt (a.b[0], b.b[0])));
+}
 
-    for (i = 0; i < NUM_IN_UINT128; i++)
-	if (a.b[i] != b.b[i])
-	    return 0;
-    return 1;
+const int
+_cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b)
+{
+    return (_cairo_uint64_eq (a.b[1], b.b[1]) &&
+	    _cairo_uint64_eq (a.b[0], b.b[0]));
 }
 

Index: cairo_uint128.h
===================================================================
RCS file: /local/src/CVS/cairo_u128/cairo_uint128.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/cairo_uint128.h	25 May 2004 05:04:49 -0000	1.2
+++ b/cairo_uint128.h	25 May 2004 06:43:12 -0000	1.3
@@ -27,33 +27,33 @@
 
 #include <stdint.h>
 
-#define HAVE_UINT64_T	1
-
 #if !HAVE_UINT64_T
 
+#define CAIRO_NUM_IN_UINT64 2
+
 typedef struct _cairo_uint64 {
-    uint16_t	b[4];
+    uint32_t	b[CAIRO_NUM_IN_UINT64];
 } cairo_uint64_t;
 
-extern cairo_uint64_t
+extern const cairo_uint64_t
 _cairo_uint32_to_uint64 (uint32_t i);
 
-extern cairo_uint64_t
+extern const cairo_uint64_t
 _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b);
 
-extern cairo_uint64_t
+extern const cairo_uint64_t
 _cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b);
 
-extern cairo_uint64_t
+extern const cairo_uint64_t
 _cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b);
 
-extern cairo_uint64_t
+extern const cairo_uint64_t
 _cairo_uint32x32_64_mul (uint32_t a, uint32_t b);
 
-extern int
+extern const int
 _cairo_uint64_less (cairo_uint64_t a, cairo_uint64_t b);
 
-extern int
+extern const int
 _cairo_uint64_equal (cairo_uint64_t a, cairo_uint64_t b);
 
 #else
@@ -64,44 +64,40 @@
 #define _cairo_uint64_add(a,b)		((a) + (b))
 #define _cairo_uint64_sub(a,b)		((a) - (b))
 #define _cairo_uint64_mul(a,b)		((a) * (b))
-#define _cairo_uint32x32_64_mul(a,b)	((uint64_t) (a) * (uint64_t) (b))
-#define _cairo_uint64_less(a,b)		((a) < (b))
-#define _cairo_uint64_equal(a,b)	((a) == (b))
+#define _cairo_uint32x32_64_mul(a,b)	((uint64_t) (a) * (b))
+#define _cairo_uint64_lt(a,b)		((a) < (b))
+#define _cairo_uint64_eq(a,b)		((a) == (b))
 
 #endif
 
-#define _cairo_uint64_gt(a,b) _cairo_uint64_less(b,a)
+#define _cairo_uint64_gt(a,b) _cairo_uint64_lt(b,a)
 #define _cairo_uint64_le(a,b) (!_cairo_uint64_gt(a,b))
 #define _cairo_uint64_ge(a,b) (!_cairo_uint64_lt(a,b))
 #define _cairo_uint64_ne(a,b) (!_cairo_uint64_eq(a,b))
 
 typedef struct cairo_uint128 {
-#if HAVE_UINT64_T
-    uint32_t	b[4];
-#else
-    uint16_t	b[8];
-#endif
+    cairo_uint64_t	b[2];
 } cairo_uint128_t;
 
-extern cairo_uint128_t
+extern const cairo_uint128_t
 _cairo_uint32_to_uint128 (uint32_t i);
 
-extern cairo_uint128_t
+extern const cairo_uint128_t
 _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b);
 
-extern cairo_uint128_t
+extern const cairo_uint128_t
 _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b);
 
-extern cairo_uint128_t
+extern const cairo_uint128_t
 _cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b);
 
-extern int
-_cairo_uint128_less (cairo_uint128_t a, cairo_uint128_t b);
+extern const int
+_cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b);
 
-extern int
-_cairo_uint128_equal (cairo_uint128_t a, cairo_uint128_t b);
+extern const int
+_cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b);
 
-#define _cairo_uint128_gt(a,b) _cairo_uint128_less(b,a)
+#define _cairo_uint128_gt(a,b) _cairo_uint128_lt(b,a)
 #define _cairo_uint128_le(a,b) (!_cairo_uint128_gt(a,b))
 #define _cairo_uint128_ge(a,b) (!_cairo_uint128_lt(a,b))
 #define _cairo_uint128_ne(a,b) (!_cairo_uint128_eq(a,b))

Index: checkdata.5c
===================================================================
RCS file: /local/src/CVS/cairo_u128/checkdata.5c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/checkdata.5c	25 May 2004 05:04:49 -0000	1.2
+++ b/checkdata.5c	25 May 2004 06:43:12 -0000	1.3
@@ -30,13 +30,14 @@
 for (;;)
 {
     int[*]  n = readnums();
+    int	    bits128 = (1 << 128) - 1;
+    int	    bits64 = (1 << 64) - 1;
     int	    p = prod(n);
-    int	    dp = p & 0xffffffffffffffff;
     int	    s = sum(n);
-    printf ("%x\n", p);
-    printf ("%x\n", dp);
-    printf ("%x\n", p - s);
-    printf ("%x\n", dp - s);
-    printf ("%x\n", s);
-    printf ("%x\n", s);
+    printf ("%x\n", p & bits128);
+    printf ("%x\n", p & bits64);
+    printf ("%x\n", (p - s) & bits128);
+    printf ("%x\n", (p - s) & bits64);
+    printf ("%x\n", (s) & bits128);
+    printf ("%x\n", (s) & bits64);
 }




More information about the Commit mailing list