anymul_1.c revision 1.1.1.1
1/* 2Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006, 2007, 2008 3Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along 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 49int 50cputime () 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 61int 62cputime () 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 71static void print_posneg (mp_limb_t); 72static 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 91int 92main (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 213static void 214print_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 231static void 232mpn_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} 252