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