Upload Tizen:Base source
[external/gmp.git] / tests / devel / shift.c
1 /*
2 Copyright 1996, 1998, 1999, 2000, 2001, 2004, 2007, 2009 Free Software
3 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 <stdio.h>
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "tests.h"
25
26 #ifdef OPERATION_lshift
27 #define func __gmpn_lshift
28 #define reffunc refmpn_lshift
29 #define funcname "mpn_lshift"
30 #endif
31
32 #ifdef OPERATION_rshift
33 #define func __gmpn_rshift
34 #define reffunc refmpn_rshift
35 #define funcname "mpn_rshift"
36 #endif
37
38 #if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
39 #include <time.h>
40
41 int
42 cputime ()
43 {
44   if (CLOCKS_PER_SEC < 100000)
45     return clock () * 1000 / CLOCKS_PER_SEC;
46   return clock () / (CLOCKS_PER_SEC / 1000);
47 }
48 #else
49 #include <sys/types.h>
50 #include <sys/time.h>
51 #include <sys/resource.h>
52
53 int
54 cputime ()
55 {
56   struct rusage rus;
57
58   getrusage (0, &rus);
59   return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
60 }
61 #endif
62
63 static void mpn_print (mp_ptr, mp_size_t);
64
65 #define M * 1000000
66
67 #ifndef CLOCK
68 #error "Don't know CLOCK of your machine"
69 #endif
70
71 #ifndef OPS
72 #define OPS (CLOCK/5)
73 #endif
74 #ifndef SIZE
75 #define SIZE 496
76 #endif
77 #ifndef TIMES
78 #define TIMES OPS/(SIZE+1)
79 #endif
80
81 #ifndef CNT
82 int CNT = 4;
83 #endif
84
85 int
86 main (int argc, char **argv)
87 {
88   mp_ptr s1, dx, dy;
89   mp_limb_t cyx, cyy;
90   int i;
91   long t0, t;
92   unsigned int test;
93   int cnt = CNT;
94   mp_size_t size;
95   unsigned int ntests;
96
97   s1 = malloc (SIZE * sizeof (mp_limb_t));
98   dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
99   dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
100
101   ntests = ~(unsigned) 0;
102   if (argc == 2)
103     ntests = strtol (argv[1], 0, 0);
104
105   for (test = 1; test <= ntests; test++)
106     {
107 #if TIMES == 1 && ! defined (PRINT)
108       if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
109         {
110           printf ("\r%u", test);
111           fflush (stdout);
112         }
113 #endif
114
115 #if TIMES == 1
116       cnt = random () % (GMP_NUMB_BITS - 1) + 1;
117 #endif
118
119 #ifdef RANDOM
120       size = random () % SIZE + 1;
121 #else
122       size = SIZE;
123 #endif
124
125       dx[0] = 0x87654321;
126       dy[0] = 0x87654321;
127       dx[size+1] = 0x12345678;
128       dy[size+1] = 0x12345678;
129
130 #if TIMES != 1
131       mpn_random (s1, size);
132
133       t0 = cputime();
134       for (i = 0; i < TIMES; i++)
135         func (dx+1, s1, size, cnt);
136       t = cputime() - t0;
137       printf (funcname ":    %5ldms (%.3f cycles/limb)\n",
138               t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
139 #endif
140
141 #ifndef NOCHECK
142       mpn_random (s1, size);
143
144 #ifdef PRINT
145       printf ("cnt=%-*d ", (int) (2 * sizeof(mp_limb_t)) - 4, cnt);
146       mpn_print (s1, size);
147 #endif
148
149       /* Put garbage in the destination.  */
150       for (i = 0; i < size; i++)
151         {
152           dx[i+1] = 0xdead;
153           dy[i+1] = 0xbeef;
154         }
155
156       cyx = reffunc (dx+1, s1, size, cnt);
157       cyy = func (dy+1, s1, size, cnt);
158
159 #ifdef PRINT
160       mpn_print (&cyx, 1);
161       mpn_print (dx+1, size);
162       mpn_print (&cyy, 1);
163       mpn_print (dy+1, size);
164 #endif
165
166       if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
167           || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
168         {
169 #ifndef PRINT
170           mpn_print (&cyx, 1);
171           mpn_print (dx+1, size);
172           mpn_print (&cyy, 1);
173           mpn_print (dy+1, size);
174 #endif
175           printf ("\n");
176           if (dy[0] != 0x87654321)
177             printf ("clobbered at low end\n");
178           if (dy[size+1] != 0x12345678)
179             printf ("clobbered at high end\n");
180           printf ("TEST NUMBER %u\n", test);
181           abort();
182         }
183 #endif
184     }
185   exit (0);
186 }
187
188 static void
189 mpn_print (mp_ptr p, mp_size_t size)
190 {
191   mp_size_t i;
192
193   for (i = size - 1; i >= 0; i--)
194     {
195 #ifdef _LONG_LONG_LIMB
196       printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
197               (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
198               (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
199 #else
200       printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
201 #endif
202 #ifdef SPACE
203       if (i != 0)
204         printf (" ");
205 #endif
206     }
207   puts ("");
208 }