Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libgmp / mpn / tests / mul_1.c
1 #include <stdio.h>
2 #include "gmp.h"
3 #include "gmp-impl.h"
4 #include "longlong.h"
5
6 #ifndef USG
7 #include <sys/time.h>
8 #include <sys/resource.h>
9
10 unsigned long
11 cputime ()
12 {
13     struct rusage rus;
14
15     getrusage (0, &rus);
16     return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
17 }
18 #else
19 #include <time.h>
20
21 #ifndef CLOCKS_PER_SEC
22 #define CLOCKS_PER_SEC 1000000
23 #endif
24
25 #if CLOCKS_PER_SEC >= 10000
26 #define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
27 #else
28 #define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
29 #endif
30
31 unsigned long
32 cputime ()
33 {
34   return CLOCK_TO_MILLISEC (clock ());
35 }
36 #endif
37
38 #define M * 1000000
39
40 #ifndef CLOCK
41 #if defined (__m88k__)
42 #define CLOCK 20 M
43 #elif defined (__i386__)
44 #define CLOCK (16.666667 M)
45 #elif defined (__m68k__)
46 #define CLOCK (20 M)
47 #elif defined (_IBMR2)
48 #define CLOCK (25 M)
49 #elif defined (__sparc__)
50 #define CLOCK (20 M)
51 #elif defined (__sun__)
52 #define CLOCK (20 M)
53 #elif defined (__mips)
54 #define CLOCK (40 M)
55 #elif defined (__hppa__)
56 #define CLOCK (50 M)
57 #elif defined (__alpha)
58 #define CLOCK (133 M)
59 #else
60 #error "Don't know CLOCK of your machine"
61 #endif
62 #endif
63
64 #ifndef OPS
65 #define OPS 20000000
66 #endif
67 #ifndef SIZE
68 #define SIZE 496
69 #endif
70 #ifndef TIMES
71 #define TIMES OPS/SIZE
72 #else
73 #undef OPS
74 #define OPS (SIZE*TIMES)
75 #endif
76
77 mp_limb_t
78 refmpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
79      register mp_ptr res_ptr;
80      register mp_srcptr s1_ptr;
81      mp_size_t s1_size;
82      register mp_limb_t s2_limb;
83 {
84   register mp_limb_t cy_limb;
85   register mp_size_t j;
86   register mp_limb_t prod_high, prod_low;
87
88   /* The loop counter and index J goes from -S1_SIZE to -1.  This way
89      the loop becomes faster.  */
90   j = -s1_size;
91
92   /* Offset the base pointers to compensate for the negative indices.  */
93   s1_ptr -= j;
94   res_ptr -= j;
95
96   cy_limb = 0;
97   do
98     {
99       umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
100
101       prod_low += cy_limb;
102       cy_limb = (prod_low < cy_limb) + prod_high;
103
104       res_ptr[j] = prod_low;
105     }
106   while (++j != 0);
107
108   return cy_limb;
109 }
110
111 main (argc, argv)
112      int argc;
113      char **argv;
114 {
115   mp_limb_t s1[SIZE];
116   mp_limb_t dx[SIZE+2];
117   mp_limb_t dy[SIZE+2];
118   mp_limb_t cyx, cyy;
119   int i;
120   long t0, t;
121   int test;
122   mp_limb_t xlimb;
123   mp_size_t size;
124
125   for (test = 0; ; test++)
126     {
127 #ifdef RANDOM
128       size = (random () % SIZE + 1);
129 #else
130       size = SIZE;
131 #endif
132
133       mpn_random2 (s1, size);
134       mpn_random2 (dy+1, size);
135
136       if (random () % 0x100 == 0)
137         xlimb = 0;
138       else
139         mpn_random2 (&xlimb, 1);
140
141       dy[size+1] = 0x12345678;
142       dy[0] = 0x87654321;
143
144 #if defined (PRINT) || defined (XPRINT)
145       printf ("xlimb=%*lX\n", (int) (2 * sizeof(mp_limb_t)), xlimb);
146 #endif
147 #ifdef PRINT
148       mpn_print (s1, size);
149 #endif
150
151       MPN_COPY (dx, dy, size+2);
152       t0 = cputime();
153       for (i = 0; i < TIMES; i++)
154         cyx = refmpn_mul_1 (dx+1, s1, size, xlimb);
155       t = cputime() - t0;
156 #if TIMES != 1
157       printf ("refmpn_mul_1: %5ldms (%.2f cycles/limb)\n",
158               t,
159               ((double) t * CLOCK) / (OPS * 1000.0));
160 #endif
161
162       MPN_COPY (dx, dy, size+2);
163       t0 = cputime();
164       for (i = 0; i < TIMES; i++)
165         cyy = mpn_mul_1 (dx+1, s1, size, xlimb);
166       t = cputime() - t0;
167 #if TIMES != 1
168       printf ("mpn_mul_1:    %5ldms (%.2f cycles/limb)\n",
169               t,
170               ((double) t * CLOCK) / (OPS * 1000.0));
171 #endif
172
173       cyx = refmpn_mul_1 (dx+1, s1, size, xlimb);
174       cyy = mpn_mul_1 (dy+1, s1, size, xlimb);
175
176 #ifdef PRINT
177       printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
178       mpn_print (dx+1, size);
179       printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
180       mpn_print (dy+1, size);
181 #endif
182
183 #ifndef NOCHECK
184       if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
185           || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
186         {
187 #ifndef PRINT
188           printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
189           mpn_print (dx+1, size);
190           printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
191           mpn_print (dy+1, size);
192 #endif
193           abort();
194         }
195 #endif
196     }
197 }
198
199 mpn_print (mp_ptr p, mp_size_t size)
200 {
201   mp_size_t i;
202
203   for (i = size - 1; i >= 0; i--)
204     {
205       printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
206 #ifdef SPACE
207       if (i != 0)
208         printf (" ");
209 #endif
210     }
211   puts ("");
212 }