Upload Tizen:Base source
[external/gmp.git] / tests / devel / anymul_1.c
1 /*
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include "gmp.h"
24 #include "gmp-impl.h"
25 #include "longlong.h"
26 #include "tests.h"
27
28 #ifdef OPERATION_mul_1
29 #define func __gmpn_mul_1
30 #define reffunc refmpn_mul_1
31 #define funcname "mpn_mul_1"
32 #endif
33
34 #ifdef OPERATION_addmul_1
35 #define func __gmpn_addmul_1
36 #define reffunc refmpn_addmul_1
37 #define funcname "mpn_addmul_1"
38 #endif
39
40 #ifdef OPERATION_submul_1
41 #define func __gmpn_submul_1
42 #define reffunc refmpn_submul_1
43 #define funcname "mpn_submul_1"
44 #endif
45
46 #if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
47 #include <time.h>
48
49 int
50 cputime ()
51 {
52   if (CLOCKS_PER_SEC < 100000)
53     return clock () * 1000 / CLOCKS_PER_SEC;
54   return clock () / (CLOCKS_PER_SEC / 1000);
55 }
56 #else
57 #include <sys/types.h>
58 #include <sys/time.h>
59 #include <sys/resource.h>
60
61 int
62 cputime ()
63 {
64   struct rusage rus;
65
66   getrusage (0, &rus);
67   return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
68 }
69 #endif
70
71 static void print_posneg (mp_limb_t);
72 static void mpn_print (mp_ptr, mp_size_t);
73
74 #define LXW ((int) (2 * sizeof (mp_limb_t)))
75 #define M * 1000000
76
77 #ifndef CLOCK
78 #error "Don't know CLOCK of your machine"
79 #endif
80
81 #ifndef OPS
82 #define OPS (CLOCK/5)
83 #endif
84 #ifndef SIZE
85 #define SIZE 496
86 #endif
87 #ifndef TIMES
88 #define TIMES OPS/(SIZE+1)
89 #endif
90
91 int
92 main (int argc, char **argv)
93 {
94   mp_ptr s1, ref, rp;
95   mp_limb_t cy_ref, cy_try;
96   int i;
97   long t0, t;
98   unsigned int test;
99   mp_limb_t xlimb;
100   mp_size_t size;
101   double cyc;
102   unsigned int ntests;
103
104   s1 = malloc (SIZE * sizeof (mp_limb_t));
105   ref = malloc (SIZE * sizeof (mp_limb_t));
106   rp = malloc ((SIZE + 2) * sizeof (mp_limb_t));
107   rp++;
108
109   ntests = ~(unsigned) 0;
110   if (argc == 2)
111     ntests = strtol (argv[1], 0, 0);
112
113   for (test = 1; test <= ntests; test++)
114     {
115 #if TIMES == 1 && ! defined (PRINT)
116       if (test % (1 + 0x80000 / (SIZE + 20)) == 0)
117         {
118           printf ("\r%u", test);
119           fflush (stdout);
120         }
121 #endif
122
123 #ifdef RANDOM
124       size = random () % SIZE + 1;
125 #else
126       size = SIZE;
127 #endif
128
129       rp[-1] = 0x87654321;
130       rp[size] = 0x12345678;
131
132 #ifdef FIXED_XLIMB
133       xlimb = FIXED_XLIMB;
134 #else
135       mpn_random2 (&xlimb, 1);
136 #endif
137
138 #if TIMES != 1
139       mpn_random (s1, size);
140       mpn_random (rp, size);
141
142       MPN_COPY (ref, rp, size);
143       t0 = cputime();
144       for (i = 0; i < TIMES; i++)
145         func (ref, s1, size, xlimb);
146       t = cputime() - t0;
147       cyc = ((double) t * CLOCK) / (TIMES * size * 1000.0);
148       printf (funcname ":    %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
149               t, cyc,
150               CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
151 #endif
152
153 #ifndef NOCHECK
154       mpn_random2 (s1, size);
155 #ifdef ZERO
156       memset (rp, 0, size * sizeof *rp);
157 #else
158       mpn_random2 (rp, size);
159 #endif
160 #if defined (PRINT) || defined (XPRINT)
161       printf ("xlimb=");
162       mpn_print (&xlimb, 1);
163 #endif
164 #ifdef PRINT
165 #ifndef OPERATION_mul_1
166       printf ("%*s ", (int) (2 * sizeof(mp_limb_t)), "");
167       mpn_print (rp, size);
168 #endif
169       printf ("%*s ", (int) (2 * sizeof(mp_limb_t)), "");
170       mpn_print (s1, size);
171 #endif
172
173       MPN_COPY (ref, rp, size);
174       cy_ref = reffunc (ref, s1, size, xlimb);
175       cy_try = func (rp, s1, size, xlimb);
176
177 #ifdef PRINT
178       mpn_print (&cy_ref, 1);
179       mpn_print (ref, size);
180       mpn_print (&cy_try, 1);
181       mpn_print (rp, size);
182 #endif
183
184       if (cy_ref != cy_try || mpn_cmp (ref, rp, size) != 0
185           || rp[-1] != 0x87654321 || rp[size] != 0x12345678)
186         {
187           printf ("\n        ref%*s try%*s diff\n", LXW - 3, "", 2 * LXW - 6, "");
188           for (i = 0; i < size; i++)
189             {
190               printf ("%6d: ", i);
191               printf ("%0*llX ", LXW, (unsigned long long) ref[i]);
192               printf ("%0*llX ", LXW, (unsigned long long) rp[i]);
193               print_posneg (rp[i] - ref[i]);
194               printf ("\n");
195             }
196           printf ("retval: ");
197           printf ("%0*llX ", LXW, (unsigned long long) cy_ref);
198           printf ("%0*llX ", LXW, (unsigned long long) cy_try);
199           print_posneg (cy_try - cy_ref);
200           printf ("\n");
201           if (rp[-1] != 0x87654321)
202             printf ("clobbered at low end\n");
203           if (rp[size] != 0x12345678)
204             printf ("clobbered at high end\n");
205           printf ("TEST NUMBER %u\n", test);
206           abort();
207         }
208 #endif
209     }
210   exit (0);
211 }
212
213 static void
214 print_posneg (mp_limb_t d)
215 {
216   char buf[LXW + 2];
217   if (d == 0)
218     printf (" %*X", LXW, 0);
219   else if (-d < d)
220     {
221       sprintf (buf, "%llX", (unsigned long long) -d);
222       printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
223     }
224   else
225     {
226       sprintf (buf, "%llX", (unsigned long long) d);
227       printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
228     }
229 }
230
231 static void
232 mpn_print (mp_ptr p, mp_size_t size)
233 {
234   mp_size_t i;
235
236   for (i = size - 1; i >= 0; i--)
237     {
238 #ifdef _LONG_LONG_LIMB
239       printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
240               (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
241               (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
242 #else
243       printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
244 #endif
245 #ifdef SPACE
246       if (i != 0)
247         printf (" ");
248 #endif
249     }
250   puts ("");
251 }