xref: /netbsd-src/external/lgpl3/gmp/dist/tests/devel/try.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* Run some tests on various mpn routines.
2 
3    THIS IS A TEST PROGRAM USED ONLY FOR DEVELOPMENT.  IT'S ALMOST CERTAIN TO
4    BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE VERSIONS OF GMP.
5 
6 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2011, 2012
7 Free Software Foundation, Inc.
8 
9 This file is part of the GNU MP Library test suite.
10 
11 The GNU MP Library test suite is free software; you can redistribute it
12 and/or modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 3 of the License,
14 or (at your option) any later version.
15 
16 The GNU MP Library test suite is distributed in the hope that it will be
17 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
19 Public License for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
23 
24 
25 /* Usage: try [options] <function>...
26 
27    For example, "./try mpn_add_n" to run tests of that function.
28 
29    Combinations of alignments and overlaps are tested, with redzones above
30    or below the destinations, and with the sources write-protected.
31 
32    The number of tests performed becomes ridiculously large with all the
33    combinations, and for that reason this can't be a part of a "make check",
34    it's meant only for development.  The code isn't very pretty either.
35 
36    During development it can help to disable the redzones, since seeing the
37    rest of the destination written can show where the wrong part is, or if
38    the dst pointers are off by 1 or whatever.  The magic DEADVAL initial
39    fill (see below) will show locations never written.
40 
41    The -s option can be used to test only certain size operands, which is
42    useful if some new code doesn't yet support say sizes less than the
43    unrolling, or whatever.
44 
45    When a problem occurs it'll of course be necessary to run the program
46    under gdb to find out quite where, how and why it's going wrong.  Disable
47    the spinner with the -W option when doing this, or single stepping won't
48    work.  Using the "-1" option to run with simple data can be useful.
49 
50    New functions to test can be added in try_array[].  If a new TYPE is
51    required then add it to the existing constants, set up its parameters in
52    param_init(), and add it to the call() function.  Extra parameter fields
53    can be added if necessary, or further interpretations given to existing
54    fields.
55 
56 
57    Portability:
58 
59    This program is not designed for use on Cray vector systems under Unicos,
60    it will fail to compile due to missing _SC_PAGE_SIZE.  Those systems
61    don't really have pages or mprotect.  We could arrange to run the tests
62    without the redzones, but we haven't bothered currently.
63 
64 
65    Enhancements:
66 
67    umul_ppmm support is not very good, lots of source data is generated
68    whereas only two limbs are needed.
69 
70    Make a little scheme for interpreting the "SIZE" selections uniformly.
71 
72    Make tr->size==SIZE_2 work, for the benefit of find_a which wants just 2
73    source limbs.  Possibly increase the default repetitions in that case.
74 
75    Automatically detect gdb and disable the spinner (use -W for now).
76 
77    Make a way to re-run a failing case in the debugger.  Have an option to
78    snapshot each test case before it's run so the data is available if a
79    segv occurs.  (This should be more reliable than the current print_all()
80    in the signal handler.)
81 
82    When alignment means a dst isn't hard against the redzone, check the
83    space in between remains unchanged.
84 
85    When a source overlaps a destination, don't run both s[i].high 0 and 1,
86    as s[i].high has no effect.  Maybe encode s[i].high into overlap->s[i].
87 
88    When partial overlaps aren't done, don't loop over source alignments
89    during overlaps.
90 
91    Try to make the looping code a bit less horrible.  Right now it's pretty
92    hard to see what iterations are actually done.
93 
94    Perhaps specific setups and loops for each style of function under test
95    would be clearer than a parameterized general loop.  There's lots of
96    stuff common to all functions, but the exceptions get messy.
97 
98    When there's no overlap, run with both src>dst and src<dst.  A subtle
99    calling-conventions violation occurred in a P6 copy which depended on the
100    relative location of src and dst.
101 
102    multiplier_N is more or less a third source region for the addmul_N
103    routines, and could be done with the redzoned region scheme.
104 
105 */
106 
107 
108 /* always do assertion checking */
109 #define WANT_ASSERT 1
110 
111 #include "config.h"
112 
113 #include <errno.h>
114 #include <limits.h>
115 #include <signal.h>
116 #include <stdio.h>
117 #include <stdlib.h>
118 #include <string.h>
119 #include <time.h>
120 
121 #if HAVE_UNISTD_H
122 #include <unistd.h>
123 #endif
124 
125 #if HAVE_SYS_MMAN_H
126 #include <sys/mman.h>
127 #endif
128 
129 #include "gmp.h"
130 #include "gmp-impl.h"
131 #include "longlong.h"
132 #include "tests.h"
133 
134 
135 #if !HAVE_DECL_OPTARG
136 extern char *optarg;
137 extern int optind, opterr;
138 #endif
139 
140 #if ! HAVE_DECL_SYS_NERR
141 extern int sys_nerr;
142 #endif
143 
144 #if ! HAVE_DECL_SYS_ERRLIST
145 extern char *sys_errlist[];
146 #endif
147 
148 #if ! HAVE_STRERROR
149 char *
150 strerror (int n)
151 {
152   if (n < 0 || n >= sys_nerr)
153     return "errno out of range";
154   else
155     return sys_errlist[n];
156 }
157 #endif
158 
159 /* Rumour has it some systems lack a define of PROT_NONE. */
160 #ifndef PROT_NONE
161 #define PROT_NONE   0
162 #endif
163 
164 /* Dummy defines for when mprotect doesn't exist. */
165 #ifndef PROT_READ
166 #define PROT_READ   0
167 #endif
168 #ifndef PROT_WRITE
169 #define PROT_WRITE  0
170 #endif
171 
172 /* _SC_PAGESIZE is standard, but hpux 9 and possibly other systems have
173    _SC_PAGE_SIZE instead. */
174 #if defined (_SC_PAGE_SIZE) && ! defined (_SC_PAGESIZE)
175 #define _SC_PAGESIZE  _SC_PAGE_SIZE
176 #endif
177 
178 
179 #ifdef EXTRA_PROTOS
180 EXTRA_PROTOS
181 #endif
182 #ifdef EXTRA_PROTOS2
183 EXTRA_PROTOS2
184 #endif
185 
186 
187 #define DEFAULT_REPETITIONS  10
188 
189 int  option_repetitions = DEFAULT_REPETITIONS;
190 int  option_spinner = 1;
191 int  option_redzones = 1;
192 int  option_firstsize = 0;
193 int  option_lastsize = 500;
194 int  option_firstsize2 = 0;
195 
196 #define ALIGNMENTS          4
197 #define OVERLAPS            4
198 #define CARRY_RANDOMS       5
199 #define MULTIPLIER_RANDOMS  5
200 #define DIVISOR_RANDOMS     5
201 #define FRACTION_COUNT      4
202 
203 int  option_print = 0;
204 
205 #define DATA_TRAND  0
206 #define DATA_ZEROS  1
207 #define DATA_SEQ    2
208 #define DATA_FFS    3
209 #define DATA_2FD    4
210 int  option_data = DATA_TRAND;
211 
212 
213 mp_size_t  pagesize;
214 #define PAGESIZE_LIMBS  (pagesize / BYTES_PER_MP_LIMB)
215 
216 /* must be a multiple of the page size */
217 #define REDZONE_BYTES   (pagesize * 16)
218 #define REDZONE_LIMBS   (REDZONE_BYTES / BYTES_PER_MP_LIMB)
219 
220 
221 #define MAX3(x,y,z)   (MAX (x, MAX (y, z)))
222 
223 #if GMP_LIMB_BITS == 32
224 #define DEADVAL  CNST_LIMB(0xDEADBEEF)
225 #else
226 #define DEADVAL  CNST_LIMB(0xDEADBEEFBADDCAFE)
227 #endif
228 
229 
230 struct region_t {
231   mp_ptr     ptr;
232   mp_size_t  size;
233 };
234 
235 
236 #define TRAP_NOWHERE 0
237 #define TRAP_REF     1
238 #define TRAP_FUN     2
239 #define TRAP_SETUPS  3
240 int trap_location = TRAP_NOWHERE;
241 
242 
243 #define NUM_SOURCES  5
244 #define NUM_DESTS    2
245 
246 struct source_t {
247   struct region_t  region;
248   int        high;
249   mp_size_t  align;
250   mp_ptr     p;
251 };
252 
253 struct source_t  s[NUM_SOURCES];
254 
255 struct dest_t {
256   int        high;
257   mp_size_t  align;
258   mp_size_t  size;
259 };
260 
261 struct dest_t  d[NUM_DESTS];
262 
263 struct source_each_t {
264   mp_ptr     p;
265 };
266 
267 struct dest_each_t {
268   struct region_t  region;
269   mp_ptr     p;
270 };
271 
272 mp_size_t       size;
273 mp_size_t       size2;
274 unsigned long   shift;
275 mp_limb_t       carry;
276 mp_limb_t       divisor;
277 mp_limb_t       multiplier;
278 mp_limb_t       multiplier_N[8];
279 
280 struct each_t {
281   const char  *name;
282   struct dest_each_t    d[NUM_DESTS];
283   struct source_each_t  s[NUM_SOURCES];
284   mp_limb_t  retval;
285 };
286 
287 struct each_t  ref = { "Ref" };
288 struct each_t  fun = { "Fun" };
289 
290 #define SRC_SIZE(n)  ((n) == 1 && tr->size2 ? size2 : size)
291 
292 void validate_fail (void);
293 
294 
295 #if HAVE_TRY_NEW_C
296 #include "try-new.c"
297 #endif
298 
299 
300 typedef mp_limb_t (*tryfun_t) (ANYARGS);
301 
302 struct try_t {
303   char  retval;
304 
305   char  src[NUM_SOURCES];
306   char  dst[NUM_DESTS];
307 
308 #define SIZE_YES          1
309 #define SIZE_ALLOW_ZERO   2
310 #define SIZE_1            3  /* 1 limb  */
311 #define SIZE_2            4  /* 2 limbs */
312 #define SIZE_3            5  /* 3 limbs */
313 #define SIZE_4            6  /* 4 limbs */
314 #define SIZE_6            7  /* 6 limbs */
315 #define SIZE_FRACTION     8  /* size2 is fraction for divrem etc */
316 #define SIZE_SIZE2        9
317 #define SIZE_PLUS_1      10
318 #define SIZE_SUM         11
319 #define SIZE_DIFF        12
320 #define SIZE_DIFF_PLUS_1 13
321 #define SIZE_DIFF_PLUS_3 14
322 #define SIZE_RETVAL      15
323 #define SIZE_CEIL_HALF   16
324 #define SIZE_GET_STR     17
325 #define SIZE_PLUS_MSIZE_SUB_1 18  /* size+msize-1 */
326 #define SIZE_ODD         19
327   char  size;
328   char  size2;
329   char  dst_size[NUM_DESTS];
330 
331   /* multiplier_N size in limbs */
332   mp_size_t  msize;
333 
334   char  dst_bytes[NUM_DESTS];
335 
336   char  dst0_from_src1;
337 
338 #define CARRY_BIT     1  /* single bit 0 or 1 */
339 #define CARRY_3       2  /* 0, 1, 2 */
340 #define CARRY_4       3  /* 0 to 3 */
341 #define CARRY_LIMB    4  /* any limb value */
342 #define CARRY_DIVISOR 5  /* carry<divisor */
343   char  carry;
344 
345   /* a fudge to tell the output when to print negatives */
346   char  carry_sign;
347 
348   char  multiplier;
349   char  shift;
350 
351 #define DIVISOR_LIMB  1
352 #define DIVISOR_NORM  2
353 #define DIVISOR_ODD   3
354   char  divisor;
355 
356 #define DATA_NON_ZERO         1
357 #define DATA_GCD              2
358 #define DATA_SRC0_ODD         3
359 #define DATA_SRC0_HIGHBIT     4
360 #define DATA_SRC1_ODD         5
361 #define DATA_SRC1_ODD_PRIME   6
362 #define DATA_SRC1_HIGHBIT     7
363 #define DATA_MULTIPLE_DIVISOR 8
364 #define DATA_UDIV_QRNND       9
365   char  data;
366 
367 /* Default is allow full overlap. */
368 #define OVERLAP_NONE         1
369 #define OVERLAP_LOW_TO_HIGH  2
370 #define OVERLAP_HIGH_TO_LOW  3
371 #define OVERLAP_NOT_SRCS     4
372 #define OVERLAP_NOT_SRC2     8
373 #define OVERLAP_NOT_DST2     16
374   char  overlap;
375 
376   tryfun_t    reference;
377   const char  *reference_name;
378 
379   void        (*validate) (void);
380   const char  *validate_name;
381 };
382 
383 struct try_t  *tr;
384 
385 
386 void
387 validate_mod_34lsub1 (void)
388 {
389 #define CNST_34LSUB1   ((CNST_LIMB(1) << (3 * (GMP_NUMB_BITS / 4))) - 1)
390 
391   mp_srcptr  ptr = s[0].p;
392   int        error = 0;
393   mp_limb_t  got, got_mod, want, want_mod;
394 
395   ASSERT (size >= 1);
396 
397   got = fun.retval;
398   got_mod = got % CNST_34LSUB1;
399 
400   want = refmpn_mod_34lsub1 (ptr, size);
401   want_mod = want % CNST_34LSUB1;
402 
403   if (got_mod != want_mod)
404     {
405       gmp_printf ("got   0x%MX reduced from 0x%MX\n", got_mod, got);
406       gmp_printf ("want  0x%MX reduced from 0x%MX\n", want_mod, want);
407       error = 1;
408     }
409 
410   if (error)
411     validate_fail ();
412 }
413 
414 void
415 validate_divexact_1 (void)
416 {
417   mp_srcptr  src = s[0].p;
418   mp_srcptr  dst = fun.d[0].p;
419   int  error = 0;
420 
421   ASSERT (size >= 1);
422 
423   {
424     mp_ptr     tp = refmpn_malloc_limbs (size);
425     mp_limb_t  rem;
426 
427     rem = refmpn_divrem_1 (tp, 0, src, size, divisor);
428     if (rem != 0)
429       {
430 	gmp_printf ("Remainder a%%d == 0x%MX, mpn_divexact_1 undefined\n", rem);
431 	error = 1;
432       }
433     if (! refmpn_equal_anynail (tp, dst, size))
434       {
435 	printf ("Quotient a/d wrong\n");
436 	mpn_trace ("fun ", dst, size);
437 	mpn_trace ("want", tp, size);
438 	error = 1;
439       }
440     free (tp);
441   }
442 
443   if (error)
444     validate_fail ();
445 }
446 
447 void
448 validate_bdiv_q_1
449  (void)
450 {
451   mp_srcptr  src = s[0].p;
452   mp_srcptr  dst = fun.d[0].p;
453   int  error = 0;
454 
455   ASSERT (size >= 1);
456 
457   {
458     mp_ptr     tp = refmpn_malloc_limbs (size + 1);
459 
460     refmpn_mul_1 (tp, dst, size, divisor);
461     /* Set ignored low bits */
462     tp[0] |= (src[0] & LOW_ZEROS_MASK (divisor));
463     if (! refmpn_equal_anynail (tp, src, size))
464       {
465 	printf ("Bdiv wrong: res * divisor != src (mod B^size)\n");
466 	mpn_trace ("res ", dst, size);
467 	mpn_trace ("src ", src, size);
468 	error = 1;
469       }
470     free (tp);
471   }
472 
473   if (error)
474     validate_fail ();
475 }
476 
477 
478 void
479 validate_modexact_1c_odd (void)
480 {
481   mp_srcptr  ptr = s[0].p;
482   mp_limb_t  r = fun.retval;
483   int  error = 0;
484 
485   ASSERT (size >= 1);
486   ASSERT (divisor & 1);
487 
488   if ((r & GMP_NAIL_MASK) != 0)
489     printf ("r has non-zero nail\n");
490 
491   if (carry < divisor)
492     {
493       if (! (r < divisor))
494 	{
495 	  printf ("Don't have r < divisor\n");
496 	  error = 1;
497 	}
498     }
499   else /* carry >= divisor */
500     {
501       if (! (r <= divisor))
502 	{
503 	  printf ("Don't have r <= divisor\n");
504 	  error = 1;
505 	}
506     }
507 
508   {
509     mp_limb_t  c = carry % divisor;
510     mp_ptr     tp = refmpn_malloc_limbs (size+1);
511     mp_size_t  k;
512 
513     for (k = size-1; k <= size; k++)
514       {
515 	/* set {tp,size+1} to r*b^k + a - c */
516 	refmpn_copyi (tp, ptr, size);
517 	tp[size] = 0;
518 	ASSERT_NOCARRY (refmpn_add_1 (tp+k, tp+k, size+1-k, r));
519 	if (refmpn_sub_1 (tp, tp, size+1, c))
520 	  ASSERT_CARRY (mpn_add_1 (tp, tp, size+1, divisor));
521 
522 	if (refmpn_mod_1 (tp, size+1, divisor) == 0)
523 	  goto good_remainder;
524       }
525     printf ("Remainder matches neither r*b^(size-1) nor r*b^size\n");
526     error = 1;
527 
528   good_remainder:
529     free (tp);
530   }
531 
532   if (error)
533     validate_fail ();
534 }
535 
536 void
537 validate_modexact_1_odd (void)
538 {
539   carry = 0;
540   validate_modexact_1c_odd ();
541 }
542 
543 
544 void
545 validate_sqrtrem (void)
546 {
547   mp_srcptr  orig_ptr = s[0].p;
548   mp_size_t  orig_size = size;
549   mp_size_t  root_size = (size+1)/2;
550   mp_srcptr  root_ptr = fun.d[0].p;
551   mp_size_t  rem_size = fun.retval;
552   mp_srcptr  rem_ptr = fun.d[1].p;
553   mp_size_t  prod_size = 2*root_size;
554   mp_ptr     p;
555   int  error = 0;
556 
557   if (rem_size < 0 || rem_size > size)
558     {
559       printf ("Bad remainder size retval %ld\n", (long) rem_size);
560       validate_fail ();
561     }
562 
563   p = refmpn_malloc_limbs (prod_size);
564 
565   p[root_size] = refmpn_lshift (p, root_ptr, root_size, 1);
566   if (refmpn_cmp_twosizes (p,root_size+1, rem_ptr,rem_size) < 0)
567     {
568       printf ("Remainder bigger than 2*root\n");
569       error = 1;
570     }
571 
572   refmpn_sqr (p, root_ptr, root_size);
573   if (rem_size != 0)
574     refmpn_add (p, p, prod_size, rem_ptr, rem_size);
575   if (refmpn_cmp_twosizes (p,prod_size, orig_ptr,orig_size) != 0)
576     {
577       printf ("root^2+rem != original\n");
578       mpn_trace ("prod", p, prod_size);
579       error = 1;
580     }
581   free (p);
582 
583   if (error)
584     validate_fail ();
585 }
586 
587 
588 /* These types are indexes into the param[] array and are arbitrary so long
589    as they're all distinct and within the size of param[].  Renumber
590    whenever necessary or desired.  */
591 
592 enum {
593   TYPE_ADD = 1, TYPE_ADD_N, TYPE_ADD_NC, TYPE_SUB, TYPE_SUB_N, TYPE_SUB_NC,
594 
595   TYPE_ADD_ERR1_N, TYPE_ADD_ERR2_N, TYPE_ADD_ERR3_N,
596   TYPE_SUB_ERR1_N, TYPE_SUB_ERR2_N, TYPE_SUB_ERR3_N,
597 
598   TYPE_MUL_1, TYPE_MUL_1C,
599 
600   TYPE_MUL_2, TYPE_MUL_3, TYPE_MUL_4, TYPE_MUL_5, TYPE_MUL_6,
601 
602   TYPE_ADDMUL_1, TYPE_ADDMUL_1C, TYPE_SUBMUL_1, TYPE_SUBMUL_1C,
603 
604   TYPE_ADDMUL_2, TYPE_ADDMUL_3, TYPE_ADDMUL_4, TYPE_ADDMUL_5, TYPE_ADDMUL_6,
605   TYPE_ADDMUL_7, TYPE_ADDMUL_8,
606 
607   TYPE_ADDSUB_N, TYPE_ADDSUB_NC,
608 
609   TYPE_RSHIFT, TYPE_LSHIFT, TYPE_LSHIFTC,
610 
611   TYPE_COPY, TYPE_COPYI, TYPE_COPYD, TYPE_COM,
612 
613   TYPE_ADDLSH1_N, TYPE_ADDLSH2_N, TYPE_ADDLSH_N,
614   TYPE_ADDLSH1_N_IP1, TYPE_ADDLSH2_N_IP1, TYPE_ADDLSH_N_IP1,
615   TYPE_ADDLSH1_N_IP2, TYPE_ADDLSH2_N_IP2, TYPE_ADDLSH_N_IP2,
616   TYPE_SUBLSH1_N, TYPE_SUBLSH2_N, TYPE_SUBLSH_N,
617   TYPE_SUBLSH1_N_IP1, TYPE_SUBLSH2_N_IP1, TYPE_SUBLSH_N_IP1,
618   TYPE_RSBLSH1_N, TYPE_RSBLSH2_N, TYPE_RSBLSH_N,
619   TYPE_RSH1ADD_N, TYPE_RSH1SUB_N,
620 
621   TYPE_ADDLSH1_NC, TYPE_ADDLSH2_NC, TYPE_ADDLSH_NC,
622   TYPE_SUBLSH1_NC, TYPE_SUBLSH2_NC, TYPE_SUBLSH_NC,
623   TYPE_RSBLSH1_NC, TYPE_RSBLSH2_NC, TYPE_RSBLSH_NC,
624 
625   TYPE_ADDCND_N, TYPE_SUBCND_N,
626 
627   TYPE_MOD_1, TYPE_MOD_1C, TYPE_DIVMOD_1, TYPE_DIVMOD_1C, TYPE_DIVREM_1,
628   TYPE_DIVREM_1C, TYPE_PREINV_DIVREM_1, TYPE_DIVREM_2, TYPE_PREINV_MOD_1,
629   TYPE_MOD_34LSUB1, TYPE_UDIV_QRNND, TYPE_UDIV_QRNND_R,
630 
631   TYPE_DIVEXACT_1, TYPE_BDIV_Q_1, TYPE_DIVEXACT_BY3, TYPE_DIVEXACT_BY3C,
632   TYPE_MODEXACT_1_ODD, TYPE_MODEXACT_1C_ODD,
633 
634   TYPE_INVERT, TYPE_BINVERT,
635 
636   TYPE_GCD, TYPE_GCD_1, TYPE_GCD_FINDA, TYPE_MPZ_JACOBI, TYPE_MPZ_KRONECKER,
637   TYPE_MPZ_KRONECKER_UI, TYPE_MPZ_KRONECKER_SI, TYPE_MPZ_UI_KRONECKER,
638   TYPE_MPZ_SI_KRONECKER, TYPE_MPZ_LEGENDRE,
639 
640   TYPE_AND_N, TYPE_NAND_N, TYPE_ANDN_N, TYPE_IOR_N, TYPE_IORN_N, TYPE_NIOR_N,
641   TYPE_XOR_N, TYPE_XNOR_N,
642 
643   TYPE_MUL_MN, TYPE_MUL_N, TYPE_SQR, TYPE_UMUL_PPMM, TYPE_UMUL_PPMM_R,
644   TYPE_MULLO_N, TYPE_MULMID_MN, TYPE_MULMID_N,
645 
646   TYPE_SBPI1_DIV_QR, TYPE_TDIV_QR,
647 
648   TYPE_SQRTREM, TYPE_ZERO, TYPE_GET_STR, TYPE_POPCOUNT, TYPE_HAMDIST,
649 
650   TYPE_EXTRA
651 };
652 
653 struct try_t  param[TYPE_EXTRA];
654 
655 
656 void
657 param_init (void)
658 {
659   struct try_t  *p;
660 
661 #define COPY(index)  memcpy (p, &param[index], sizeof (*p))
662 
663 #if HAVE_STRINGIZE
664 #define REFERENCE(fun)                  \
665   p->reference = (tryfun_t) fun;        \
666   p->reference_name = #fun
667 #define VALIDATE(fun)           \
668   p->validate = fun;            \
669   p->validate_name = #fun
670 #else
671 #define REFERENCE(fun)                  \
672   p->reference = (tryfun_t) fun;        \
673   p->reference_name = "fun"
674 #define VALIDATE(fun)           \
675   p->validate = fun;            \
676   p->validate_name = "fun"
677 #endif
678 
679 
680   p = &param[TYPE_ADD_N];
681   p->retval = 1;
682   p->dst[0] = 1;
683   p->src[0] = 1;
684   p->src[1] = 1;
685   REFERENCE (refmpn_add_n);
686 
687   p = &param[TYPE_ADD_NC];
688   COPY (TYPE_ADD_N);
689   p->carry = CARRY_BIT;
690   REFERENCE (refmpn_add_nc);
691 
692   p = &param[TYPE_SUB_N];
693   COPY (TYPE_ADD_N);
694   REFERENCE (refmpn_sub_n);
695 
696   p = &param[TYPE_SUB_NC];
697   COPY (TYPE_ADD_NC);
698   REFERENCE (refmpn_sub_nc);
699 
700   p = &param[TYPE_ADD];
701   COPY (TYPE_ADD_N);
702   p->size = SIZE_ALLOW_ZERO;
703   p->size2 = 1;
704   REFERENCE (refmpn_add);
705 
706   p = &param[TYPE_SUB];
707   COPY (TYPE_ADD);
708   REFERENCE (refmpn_sub);
709 
710 
711   p = &param[TYPE_ADD_ERR1_N];
712   p->retval = 1;
713   p->dst[0] = 1;
714   p->dst[1] = 1;
715   p->src[0] = 1;
716   p->src[1] = 1;
717   p->src[2] = 1;
718   p->dst_size[1] = SIZE_2;
719   p->carry = CARRY_BIT;
720   p->overlap = OVERLAP_NOT_DST2;
721   REFERENCE (refmpn_add_err1_n);
722 
723   p = &param[TYPE_SUB_ERR1_N];
724   COPY (TYPE_ADD_ERR1_N);
725   REFERENCE (refmpn_sub_err1_n);
726 
727   p = &param[TYPE_ADD_ERR2_N];
728   COPY (TYPE_ADD_ERR1_N);
729   p->src[3] = 1;
730   p->dst_size[1] = SIZE_4;
731   REFERENCE (refmpn_add_err2_n);
732 
733   p = &param[TYPE_SUB_ERR2_N];
734   COPY (TYPE_ADD_ERR2_N);
735   REFERENCE (refmpn_sub_err2_n);
736 
737   p = &param[TYPE_ADD_ERR3_N];
738   COPY (TYPE_ADD_ERR2_N);
739   p->src[4] = 1;
740   p->dst_size[1] = SIZE_6;
741   REFERENCE (refmpn_add_err3_n);
742 
743   p = &param[TYPE_SUB_ERR3_N];
744   COPY (TYPE_ADD_ERR3_N);
745   REFERENCE (refmpn_sub_err3_n);
746 
747   p = &param[TYPE_ADDCND_N];
748   COPY (TYPE_ADD_N);
749   p->carry = CARRY_BIT;
750   REFERENCE (refmpn_addcnd_n);
751 
752   p = &param[TYPE_SUBCND_N];
753   COPY (TYPE_ADD_N);
754   p->carry = CARRY_BIT;
755   REFERENCE (refmpn_subcnd_n);
756 
757 
758   p = &param[TYPE_MUL_1];
759   p->retval = 1;
760   p->dst[0] = 1;
761   p->src[0] = 1;
762   p->multiplier = 1;
763   p->overlap = OVERLAP_LOW_TO_HIGH;
764   REFERENCE (refmpn_mul_1);
765 
766   p = &param[TYPE_MUL_1C];
767   COPY (TYPE_MUL_1);
768   p->carry = CARRY_LIMB;
769   REFERENCE (refmpn_mul_1c);
770 
771 
772   p = &param[TYPE_MUL_2];
773   p->retval = 1;
774   p->dst[0] = 1;
775   p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
776   p->src[0] = 1;
777   p->src[1] = 1;
778   p->msize = 2;
779   p->overlap = OVERLAP_NOT_SRC2;
780   REFERENCE (refmpn_mul_2);
781 
782   p = &param[TYPE_MUL_3];
783   COPY (TYPE_MUL_2);
784   p->msize = 3;
785   REFERENCE (refmpn_mul_3);
786 
787   p = &param[TYPE_MUL_4];
788   COPY (TYPE_MUL_2);
789   p->msize = 4;
790   REFERENCE (refmpn_mul_4);
791 
792   p = &param[TYPE_MUL_5];
793   COPY (TYPE_MUL_2);
794   p->msize = 5;
795   REFERENCE (refmpn_mul_5);
796 
797   p = &param[TYPE_MUL_6];
798   COPY (TYPE_MUL_2);
799   p->msize = 6;
800   REFERENCE (refmpn_mul_6);
801 
802 
803   p = &param[TYPE_ADDMUL_1];
804   p->retval = 1;
805   p->dst[0] = 1;
806   p->src[0] = 1;
807   p->multiplier = 1;
808   p->dst0_from_src1 = 1;
809   REFERENCE (refmpn_addmul_1);
810 
811   p = &param[TYPE_ADDMUL_1C];
812   COPY (TYPE_ADDMUL_1);
813   p->carry = CARRY_LIMB;
814   REFERENCE (refmpn_addmul_1c);
815 
816   p = &param[TYPE_SUBMUL_1];
817   COPY (TYPE_ADDMUL_1);
818   REFERENCE (refmpn_submul_1);
819 
820   p = &param[TYPE_SUBMUL_1C];
821   COPY (TYPE_ADDMUL_1C);
822   REFERENCE (refmpn_submul_1c);
823 
824 
825   p = &param[TYPE_ADDMUL_2];
826   p->retval = 1;
827   p->dst[0] = 1;
828   p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
829   p->src[0] = 1;
830   p->src[1] = 1;
831   p->msize = 2;
832   p->dst0_from_src1 = 1;
833   p->overlap = OVERLAP_NONE;
834   REFERENCE (refmpn_addmul_2);
835 
836   p = &param[TYPE_ADDMUL_3];
837   COPY (TYPE_ADDMUL_2);
838   p->msize = 3;
839   REFERENCE (refmpn_addmul_3);
840 
841   p = &param[TYPE_ADDMUL_4];
842   COPY (TYPE_ADDMUL_2);
843   p->msize = 4;
844   REFERENCE (refmpn_addmul_4);
845 
846   p = &param[TYPE_ADDMUL_5];
847   COPY (TYPE_ADDMUL_2);
848   p->msize = 5;
849   REFERENCE (refmpn_addmul_5);
850 
851   p = &param[TYPE_ADDMUL_6];
852   COPY (TYPE_ADDMUL_2);
853   p->msize = 6;
854   REFERENCE (refmpn_addmul_6);
855 
856   p = &param[TYPE_ADDMUL_7];
857   COPY (TYPE_ADDMUL_2);
858   p->msize = 7;
859   REFERENCE (refmpn_addmul_7);
860 
861   p = &param[TYPE_ADDMUL_8];
862   COPY (TYPE_ADDMUL_2);
863   p->msize = 8;
864   REFERENCE (refmpn_addmul_8);
865 
866 
867   p = &param[TYPE_AND_N];
868   p->dst[0] = 1;
869   p->src[0] = 1;
870   p->src[1] = 1;
871   REFERENCE (refmpn_and_n);
872 
873   p = &param[TYPE_ANDN_N];
874   COPY (TYPE_AND_N);
875   REFERENCE (refmpn_andn_n);
876 
877   p = &param[TYPE_NAND_N];
878   COPY (TYPE_AND_N);
879   REFERENCE (refmpn_nand_n);
880 
881   p = &param[TYPE_IOR_N];
882   COPY (TYPE_AND_N);
883   REFERENCE (refmpn_ior_n);
884 
885   p = &param[TYPE_IORN_N];
886   COPY (TYPE_AND_N);
887   REFERENCE (refmpn_iorn_n);
888 
889   p = &param[TYPE_NIOR_N];
890   COPY (TYPE_AND_N);
891   REFERENCE (refmpn_nior_n);
892 
893   p = &param[TYPE_XOR_N];
894   COPY (TYPE_AND_N);
895   REFERENCE (refmpn_xor_n);
896 
897   p = &param[TYPE_XNOR_N];
898   COPY (TYPE_AND_N);
899   REFERENCE (refmpn_xnor_n);
900 
901 
902   p = &param[TYPE_ADDSUB_N];
903   p->retval = 1;
904   p->dst[0] = 1;
905   p->dst[1] = 1;
906   p->src[0] = 1;
907   p->src[1] = 1;
908   REFERENCE (refmpn_add_n_sub_n);
909 
910   p = &param[TYPE_ADDSUB_NC];
911   COPY (TYPE_ADDSUB_N);
912   p->carry = CARRY_4;
913   REFERENCE (refmpn_add_n_sub_nc);
914 
915 
916   p = &param[TYPE_COPY];
917   p->dst[0] = 1;
918   p->src[0] = 1;
919   p->overlap = OVERLAP_NONE;
920   p->size = SIZE_ALLOW_ZERO;
921   REFERENCE (refmpn_copy);
922 
923   p = &param[TYPE_COPYI];
924   p->dst[0] = 1;
925   p->src[0] = 1;
926   p->overlap = OVERLAP_LOW_TO_HIGH;
927   p->size = SIZE_ALLOW_ZERO;
928   REFERENCE (refmpn_copyi);
929 
930   p = &param[TYPE_COPYD];
931   p->dst[0] = 1;
932   p->src[0] = 1;
933   p->overlap = OVERLAP_HIGH_TO_LOW;
934   p->size = SIZE_ALLOW_ZERO;
935   REFERENCE (refmpn_copyd);
936 
937   p = &param[TYPE_COM];
938   p->dst[0] = 1;
939   p->src[0] = 1;
940   REFERENCE (refmpn_com);
941 
942 
943   p = &param[TYPE_ADDLSH1_N];
944   COPY (TYPE_ADD_N);
945   REFERENCE (refmpn_addlsh1_n);
946 
947   p = &param[TYPE_ADDLSH2_N];
948   COPY (TYPE_ADD_N);
949   REFERENCE (refmpn_addlsh2_n);
950 
951   p = &param[TYPE_ADDLSH_N];
952   COPY (TYPE_ADD_N);
953   p->shift = 1;
954   REFERENCE (refmpn_addlsh_n);
955 
956   p = &param[TYPE_ADDLSH1_N_IP1];
957   p->retval = 1;
958   p->dst[0] = 1;
959   p->src[0] = 1;
960   p->dst0_from_src1 = 1;
961   REFERENCE (refmpn_addlsh1_n_ip1);
962 
963   p = &param[TYPE_ADDLSH2_N_IP1];
964   COPY (TYPE_ADDLSH1_N_IP1);
965   REFERENCE (refmpn_addlsh2_n_ip1);
966 
967   p = &param[TYPE_ADDLSH_N_IP1];
968   COPY (TYPE_ADDLSH1_N_IP1);
969   p->shift = 1;
970   REFERENCE (refmpn_addlsh_n_ip1);
971 
972   p = &param[TYPE_ADDLSH1_N_IP2];
973   COPY (TYPE_ADDLSH1_N_IP1);
974   REFERENCE (refmpn_addlsh1_n_ip2);
975 
976   p = &param[TYPE_ADDLSH2_N_IP2];
977   COPY (TYPE_ADDLSH1_N_IP1);
978   REFERENCE (refmpn_addlsh2_n_ip2);
979 
980   p = &param[TYPE_ADDLSH_N_IP2];
981   COPY (TYPE_ADDLSH_N_IP1);
982   REFERENCE (refmpn_addlsh_n_ip2);
983 
984   p = &param[TYPE_SUBLSH1_N];
985   COPY (TYPE_ADD_N);
986   REFERENCE (refmpn_sublsh1_n);
987 
988   p = &param[TYPE_SUBLSH2_N];
989   COPY (TYPE_ADD_N);
990   REFERENCE (refmpn_sublsh2_n);
991 
992   p = &param[TYPE_SUBLSH_N];
993   COPY (TYPE_ADDLSH_N);
994   REFERENCE (refmpn_sublsh_n);
995 
996   p = &param[TYPE_SUBLSH1_N_IP1];
997   COPY (TYPE_ADDLSH1_N_IP1);
998   REFERENCE (refmpn_sublsh1_n_ip1);
999 
1000   p = &param[TYPE_SUBLSH2_N_IP1];
1001   COPY (TYPE_ADDLSH1_N_IP1);
1002   REFERENCE (refmpn_sublsh2_n_ip1);
1003 
1004   p = &param[TYPE_SUBLSH_N_IP1];
1005   COPY (TYPE_ADDLSH_N_IP1);
1006   REFERENCE (refmpn_sublsh_n_ip1);
1007 
1008   p = &param[TYPE_RSBLSH1_N];
1009   COPY (TYPE_ADD_N);
1010   REFERENCE (refmpn_rsblsh1_n);
1011 
1012   p = &param[TYPE_RSBLSH2_N];
1013   COPY (TYPE_ADD_N);
1014   REFERENCE (refmpn_rsblsh2_n);
1015 
1016   p = &param[TYPE_RSBLSH_N];
1017   COPY (TYPE_ADDLSH_N);
1018   REFERENCE (refmpn_rsblsh_n);
1019 
1020   p = &param[TYPE_RSH1ADD_N];
1021   COPY (TYPE_ADD_N);
1022   REFERENCE (refmpn_rsh1add_n);
1023 
1024   p = &param[TYPE_RSH1SUB_N];
1025   COPY (TYPE_ADD_N);
1026   REFERENCE (refmpn_rsh1sub_n);
1027 
1028 
1029   p = &param[TYPE_ADDLSH1_NC];
1030   COPY (TYPE_ADDLSH1_N);
1031   p->carry = CARRY_3;
1032   REFERENCE (refmpn_addlsh1_nc);
1033 
1034   p = &param[TYPE_ADDLSH2_NC];
1035   COPY (TYPE_ADDLSH2_N);
1036   p->carry = CARRY_4; /* FIXME */
1037   REFERENCE (refmpn_addlsh2_nc);
1038 
1039   p = &param[TYPE_ADDLSH_NC];
1040   COPY (TYPE_ADDLSH_N);
1041   p->carry = CARRY_BIT; /* FIXME */
1042   REFERENCE (refmpn_addlsh_nc);
1043 
1044   p = &param[TYPE_SUBLSH1_NC];
1045   COPY (TYPE_ADDLSH1_NC);
1046   REFERENCE (refmpn_sublsh1_nc);
1047 
1048   p = &param[TYPE_SUBLSH2_NC];
1049   COPY (TYPE_ADDLSH2_NC);
1050   REFERENCE (refmpn_sublsh2_nc);
1051 
1052   p = &param[TYPE_SUBLSH_NC];
1053   COPY (TYPE_ADDLSH_NC);
1054   REFERENCE (refmpn_sublsh_nc);
1055 
1056   p = &param[TYPE_RSBLSH1_NC];
1057   COPY (TYPE_RSBLSH1_N);
1058   p->carry = CARRY_BIT; /* FIXME */
1059   REFERENCE (refmpn_rsblsh1_nc);
1060 
1061   p = &param[TYPE_RSBLSH2_NC];
1062   COPY (TYPE_RSBLSH2_N);
1063   p->carry = CARRY_4; /* FIXME */
1064   REFERENCE (refmpn_rsblsh2_nc);
1065 
1066   p = &param[TYPE_RSBLSH_NC];
1067   COPY (TYPE_RSBLSH_N);
1068   p->carry = CARRY_BIT; /* FIXME */
1069   REFERENCE (refmpn_rsblsh_nc);
1070 
1071 
1072   p = &param[TYPE_MOD_1];
1073   p->retval = 1;
1074   p->src[0] = 1;
1075   p->size = SIZE_ALLOW_ZERO;
1076   p->divisor = DIVISOR_LIMB;
1077   REFERENCE (refmpn_mod_1);
1078 
1079   p = &param[TYPE_MOD_1C];
1080   COPY (TYPE_MOD_1);
1081   p->carry = CARRY_DIVISOR;
1082   REFERENCE (refmpn_mod_1c);
1083 
1084   p = &param[TYPE_DIVMOD_1];
1085   COPY (TYPE_MOD_1);
1086   p->dst[0] = 1;
1087   REFERENCE (refmpn_divmod_1);
1088 
1089   p = &param[TYPE_DIVMOD_1C];
1090   COPY (TYPE_DIVMOD_1);
1091   p->carry = CARRY_DIVISOR;
1092   REFERENCE (refmpn_divmod_1c);
1093 
1094   p = &param[TYPE_DIVREM_1];
1095   COPY (TYPE_DIVMOD_1);
1096   p->size2 = SIZE_FRACTION;
1097   p->dst_size[0] = SIZE_SUM;
1098   REFERENCE (refmpn_divrem_1);
1099 
1100   p = &param[TYPE_DIVREM_1C];
1101   COPY (TYPE_DIVREM_1);
1102   p->carry = CARRY_DIVISOR;
1103   REFERENCE (refmpn_divrem_1c);
1104 
1105   p = &param[TYPE_PREINV_DIVREM_1];
1106   COPY (TYPE_DIVREM_1);
1107   p->size = SIZE_YES; /* ie. no size==0 */
1108   REFERENCE (refmpn_preinv_divrem_1);
1109 
1110   p = &param[TYPE_PREINV_MOD_1];
1111   p->retval = 1;
1112   p->src[0] = 1;
1113   p->divisor = DIVISOR_NORM;
1114   REFERENCE (refmpn_preinv_mod_1);
1115 
1116   p = &param[TYPE_MOD_34LSUB1];
1117   p->retval = 1;
1118   p->src[0] = 1;
1119   VALIDATE (validate_mod_34lsub1);
1120 
1121   p = &param[TYPE_UDIV_QRNND];
1122   p->retval = 1;
1123   p->src[0] = 1;
1124   p->dst[0] = 1;
1125   p->dst_size[0] = SIZE_1;
1126   p->divisor = UDIV_NEEDS_NORMALIZATION ? DIVISOR_NORM : DIVISOR_LIMB;
1127   p->data = DATA_UDIV_QRNND;
1128   p->overlap = OVERLAP_NONE;
1129   REFERENCE (refmpn_udiv_qrnnd);
1130 
1131   p = &param[TYPE_UDIV_QRNND_R];
1132   COPY (TYPE_UDIV_QRNND);
1133   REFERENCE (refmpn_udiv_qrnnd_r);
1134 
1135 
1136   p = &param[TYPE_DIVEXACT_1];
1137   p->dst[0] = 1;
1138   p->src[0] = 1;
1139   p->divisor = DIVISOR_LIMB;
1140   p->data = DATA_MULTIPLE_DIVISOR;
1141   VALIDATE (validate_divexact_1);
1142   REFERENCE (refmpn_divmod_1);
1143 
1144   p = &param[TYPE_BDIV_Q_1];
1145   p->dst[0] = 1;
1146   p->src[0] = 1;
1147   p->divisor = DIVISOR_LIMB;
1148   VALIDATE (validate_bdiv_q_1);
1149 
1150   p = &param[TYPE_DIVEXACT_BY3];
1151   p->retval = 1;
1152   p->dst[0] = 1;
1153   p->src[0] = 1;
1154   REFERENCE (refmpn_divexact_by3);
1155 
1156   p = &param[TYPE_DIVEXACT_BY3C];
1157   COPY (TYPE_DIVEXACT_BY3);
1158   p->carry = CARRY_3;
1159   REFERENCE (refmpn_divexact_by3c);
1160 
1161 
1162   p = &param[TYPE_MODEXACT_1_ODD];
1163   p->retval = 1;
1164   p->src[0] = 1;
1165   p->divisor = DIVISOR_ODD;
1166   VALIDATE (validate_modexact_1_odd);
1167 
1168   p = &param[TYPE_MODEXACT_1C_ODD];
1169   COPY (TYPE_MODEXACT_1_ODD);
1170   p->carry = CARRY_LIMB;
1171   VALIDATE (validate_modexact_1c_odd);
1172 
1173 
1174   p = &param[TYPE_GCD_1];
1175   p->retval = 1;
1176   p->src[0] = 1;
1177   p->data = DATA_NON_ZERO;
1178   p->divisor = DIVISOR_LIMB;
1179   REFERENCE (refmpn_gcd_1);
1180 
1181   p = &param[TYPE_GCD];
1182   p->retval = 1;
1183   p->dst[0] = 1;
1184   p->src[0] = 1;
1185   p->src[1] = 1;
1186   p->size2 = 1;
1187   p->dst_size[0] = SIZE_RETVAL;
1188   p->overlap = OVERLAP_NOT_SRCS;
1189   p->data = DATA_GCD;
1190   REFERENCE (refmpn_gcd);
1191 
1192 
1193   p = &param[TYPE_MPZ_LEGENDRE];
1194   p->retval = 1;
1195   p->src[0] = 1;
1196   p->size = SIZE_ALLOW_ZERO;
1197   p->src[1] = 1;
1198   p->data = DATA_SRC1_ODD_PRIME;
1199   p->size2 = 1;
1200   p->carry = CARRY_BIT;
1201   p->carry_sign = 1;
1202   REFERENCE (refmpz_legendre);
1203 
1204   p = &param[TYPE_MPZ_JACOBI];
1205   p->retval = 1;
1206   p->src[0] = 1;
1207   p->size = SIZE_ALLOW_ZERO;
1208   p->src[1] = 1;
1209   p->data = DATA_SRC1_ODD;
1210   p->size2 = 1;
1211   p->carry = CARRY_BIT;
1212   p->carry_sign = 1;
1213   REFERENCE (refmpz_jacobi);
1214 
1215   p = &param[TYPE_MPZ_KRONECKER];
1216   p->retval = 1;
1217   p->src[0] = 1;
1218   p->size = SIZE_ALLOW_ZERO;
1219   p->src[1] = 1;
1220   p->data = 0;
1221   p->size2 = 1;
1222   p->carry = CARRY_4;
1223   p->carry_sign = 1;
1224   REFERENCE (refmpz_kronecker);
1225 
1226 
1227   p = &param[TYPE_MPZ_KRONECKER_UI];
1228   p->retval = 1;
1229   p->src[0] = 1;
1230   p->size = SIZE_ALLOW_ZERO;
1231   p->multiplier = 1;
1232   p->carry = CARRY_BIT;
1233   REFERENCE (refmpz_kronecker_ui);
1234 
1235   p = &param[TYPE_MPZ_KRONECKER_SI];
1236   COPY (TYPE_MPZ_KRONECKER_UI);
1237   REFERENCE (refmpz_kronecker_si);
1238 
1239   p = &param[TYPE_MPZ_UI_KRONECKER];
1240   COPY (TYPE_MPZ_KRONECKER_UI);
1241   REFERENCE (refmpz_ui_kronecker);
1242 
1243   p = &param[TYPE_MPZ_SI_KRONECKER];
1244   COPY (TYPE_MPZ_KRONECKER_UI);
1245   REFERENCE (refmpz_si_kronecker);
1246 
1247 
1248   p = &param[TYPE_SQR];
1249   p->dst[0] = 1;
1250   p->src[0] = 1;
1251   p->dst_size[0] = SIZE_SUM;
1252   p->overlap = OVERLAP_NONE;
1253   REFERENCE (refmpn_sqr);
1254 
1255   p = &param[TYPE_MUL_N];
1256   COPY (TYPE_SQR);
1257   p->src[1] = 1;
1258   REFERENCE (refmpn_mul_n);
1259 
1260   p = &param[TYPE_MULLO_N];
1261   COPY (TYPE_MUL_N);
1262   p->dst_size[0] = 0;
1263   REFERENCE (refmpn_mullo_n);
1264 
1265   p = &param[TYPE_MUL_MN];
1266   COPY (TYPE_MUL_N);
1267   p->size2 = 1;
1268   REFERENCE (refmpn_mul_basecase);
1269 
1270   p = &param[TYPE_MULMID_MN];
1271   COPY (TYPE_MUL_MN);
1272   p->dst_size[0] = SIZE_DIFF_PLUS_3;
1273   REFERENCE (refmpn_mulmid_basecase);
1274 
1275   p = &param[TYPE_MULMID_N];
1276   COPY (TYPE_MUL_N);
1277   p->size = SIZE_ODD;
1278   p->size2 = SIZE_CEIL_HALF;
1279   p->dst_size[0] = SIZE_DIFF_PLUS_3;
1280   REFERENCE (refmpn_mulmid_n);
1281 
1282   p = &param[TYPE_UMUL_PPMM];
1283   p->retval = 1;
1284   p->src[0] = 1;
1285   p->dst[0] = 1;
1286   p->dst_size[0] = SIZE_1;
1287   p->overlap = OVERLAP_NONE;
1288   REFERENCE (refmpn_umul_ppmm);
1289 
1290   p = &param[TYPE_UMUL_PPMM_R];
1291   COPY (TYPE_UMUL_PPMM);
1292   REFERENCE (refmpn_umul_ppmm_r);
1293 
1294 
1295   p = &param[TYPE_RSHIFT];
1296   p->retval = 1;
1297   p->dst[0] = 1;
1298   p->src[0] = 1;
1299   p->shift = 1;
1300   p->overlap = OVERLAP_LOW_TO_HIGH;
1301   REFERENCE (refmpn_rshift);
1302 
1303   p = &param[TYPE_LSHIFT];
1304   COPY (TYPE_RSHIFT);
1305   p->overlap = OVERLAP_HIGH_TO_LOW;
1306   REFERENCE (refmpn_lshift);
1307 
1308   p = &param[TYPE_LSHIFTC];
1309   COPY (TYPE_RSHIFT);
1310   p->overlap = OVERLAP_HIGH_TO_LOW;
1311   REFERENCE (refmpn_lshiftc);
1312 
1313 
1314   p = &param[TYPE_POPCOUNT];
1315   p->retval = 1;
1316   p->src[0] = 1;
1317   REFERENCE (refmpn_popcount);
1318 
1319   p = &param[TYPE_HAMDIST];
1320   COPY (TYPE_POPCOUNT);
1321   p->src[1] = 1;
1322   REFERENCE (refmpn_hamdist);
1323 
1324 
1325   p = &param[TYPE_SBPI1_DIV_QR];
1326   p->retval = 1;
1327   p->dst[0] = 1;
1328   p->dst[1] = 1;
1329   p->src[0] = 1;
1330   p->src[1] = 1;
1331   p->data = DATA_SRC1_HIGHBIT;
1332   p->size2 = 1;
1333   p->dst_size[0] = SIZE_DIFF;
1334   p->overlap = OVERLAP_NONE;
1335   REFERENCE (refmpn_sb_div_qr);
1336 
1337   p = &param[TYPE_TDIV_QR];
1338   p->dst[0] = 1;
1339   p->dst[1] = 1;
1340   p->src[0] = 1;
1341   p->src[1] = 1;
1342   p->size2 = 1;
1343   p->dst_size[0] = SIZE_DIFF_PLUS_1;
1344   p->dst_size[1] = SIZE_SIZE2;
1345   p->overlap = OVERLAP_NONE;
1346   REFERENCE (refmpn_tdiv_qr);
1347 
1348   p = &param[TYPE_SQRTREM];
1349   p->retval = 1;
1350   p->dst[0] = 1;
1351   p->dst[1] = 1;
1352   p->src[0] = 1;
1353   p->dst_size[0] = SIZE_CEIL_HALF;
1354   p->dst_size[1] = SIZE_RETVAL;
1355   p->overlap = OVERLAP_NONE;
1356   VALIDATE (validate_sqrtrem);
1357   REFERENCE (refmpn_sqrtrem);
1358 
1359   p = &param[TYPE_ZERO];
1360   p->dst[0] = 1;
1361   p->size = SIZE_ALLOW_ZERO;
1362   REFERENCE (refmpn_zero);
1363 
1364   p = &param[TYPE_GET_STR];
1365   p->retval = 1;
1366   p->src[0] = 1;
1367   p->size = SIZE_ALLOW_ZERO;
1368   p->dst[0] = 1;
1369   p->dst[1] = 1;
1370   p->dst_size[0] = SIZE_GET_STR;
1371   p->dst_bytes[0] = 1;
1372   p->overlap = OVERLAP_NONE;
1373   REFERENCE (refmpn_get_str);
1374 
1375   p = &param[TYPE_BINVERT];
1376   p->dst[0] = 1;
1377   p->src[0] = 1;
1378   p->data = DATA_SRC0_ODD;
1379   p->overlap = OVERLAP_NONE;
1380   REFERENCE (refmpn_binvert);
1381 
1382   p = &param[TYPE_INVERT];
1383   p->dst[0] = 1;
1384   p->src[0] = 1;
1385   p->data = DATA_SRC0_HIGHBIT;
1386   p->overlap = OVERLAP_NONE;
1387   REFERENCE (refmpn_invert);
1388 
1389 #ifdef EXTRA_PARAM_INIT
1390   EXTRA_PARAM_INIT
1391 #endif
1392 }
1393 
1394 
1395 /* The following are macros if there's no native versions, so wrap them in
1396    functions that can be in try_array[]. */
1397 
1398 void
1399 MPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1400 { MPN_COPY (rp, sp, size); }
1401 
1402 void
1403 MPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1404 { MPN_COPY_INCR (rp, sp, size); }
1405 
1406 void
1407 MPN_COPY_DECR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1408 { MPN_COPY_DECR (rp, sp, size); }
1409 
1410 void
1411 __GMPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1412 { __GMPN_COPY (rp, sp, size); }
1413 
1414 #ifdef __GMPN_COPY_INCR
1415 void
1416 __GMPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1417 { __GMPN_COPY_INCR (rp, sp, size); }
1418 #endif
1419 
1420 void
1421 mpn_com_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1422 { mpn_com (rp, sp, size); }
1423 
1424 void
1425 mpn_and_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1426 { mpn_and_n (rp, s1, s2, size); }
1427 
1428 void
1429 mpn_andn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1430 { mpn_andn_n (rp, s1, s2, size); }
1431 
1432 void
1433 mpn_nand_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1434 { mpn_nand_n (rp, s1, s2, size); }
1435 
1436 void
1437 mpn_ior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1438 { mpn_ior_n (rp, s1, s2, size); }
1439 
1440 void
1441 mpn_iorn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1442 { mpn_iorn_n (rp, s1, s2, size); }
1443 
1444 void
1445 mpn_nior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1446 { mpn_nior_n (rp, s1, s2, size); }
1447 
1448 void
1449 mpn_xor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1450 { mpn_xor_n (rp, s1, s2, size); }
1451 
1452 void
1453 mpn_xnor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
1454 { mpn_xnor_n (rp, s1, s2, size); }
1455 
1456 mp_limb_t
1457 udiv_qrnnd_fun (mp_limb_t *remptr, mp_limb_t n1, mp_limb_t n0, mp_limb_t d)
1458 {
1459   mp_limb_t  q;
1460   udiv_qrnnd (q, *remptr, n1, n0, d);
1461   return q;
1462 }
1463 
1464 mp_limb_t
1465 mpn_divexact_by3_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1466 {
1467   return mpn_divexact_by3 (rp, sp, size);
1468 }
1469 
1470 #if HAVE_NATIVE_mpn_addlsh1_n_ip1
1471 mp_limb_t
1472 mpn_addlsh1_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1473 {
1474   return mpn_addlsh1_n_ip1 (rp, sp, size);
1475 }
1476 #endif
1477 #if HAVE_NATIVE_mpn_addlsh2_n_ip1
1478 mp_limb_t
1479 mpn_addlsh2_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1480 {
1481   return mpn_addlsh2_n_ip1 (rp, sp, size);
1482 }
1483 #endif
1484 #if HAVE_NATIVE_mpn_addlsh_n_ip1
1485 mp_limb_t
1486 mpn_addlsh_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
1487 {
1488   return mpn_addlsh_n_ip1 (rp, sp, size, sh);
1489 }
1490 #endif
1491 #if HAVE_NATIVE_mpn_addlsh1_n_ip2
1492 mp_limb_t
1493 mpn_addlsh1_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1494 {
1495   return mpn_addlsh1_n_ip2 (rp, sp, size);
1496 }
1497 #endif
1498 #if HAVE_NATIVE_mpn_addlsh2_n_ip2
1499 mp_limb_t
1500 mpn_addlsh2_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1501 {
1502   return mpn_addlsh2_n_ip2 (rp, sp, size);
1503 }
1504 #endif
1505 #if HAVE_NATIVE_mpn_addlsh_n_ip2
1506 mp_limb_t
1507 mpn_addlsh_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
1508 {
1509   return mpn_addlsh_n_ip2 (rp, sp, size, sh);
1510 }
1511 #endif
1512 #if HAVE_NATIVE_mpn_sublsh1_n_ip1
1513 mp_limb_t
1514 mpn_sublsh1_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1515 {
1516   return mpn_sublsh1_n_ip1 (rp, sp, size);
1517 }
1518 #endif
1519 #if HAVE_NATIVE_mpn_sublsh2_n_ip1
1520 mp_limb_t
1521 mpn_sublsh2_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
1522 {
1523   return mpn_sublsh2_n_ip1 (rp, sp, size);
1524 }
1525 #endif
1526 #if HAVE_NATIVE_mpn_sublsh_n_ip1
1527 mp_limb_t
1528 mpn_sublsh_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
1529 {
1530   return mpn_sublsh_n_ip1 (rp, sp, size, sh);
1531 }
1532 #endif
1533 
1534 mp_limb_t
1535 mpn_modexact_1_odd_fun (mp_srcptr ptr, mp_size_t size, mp_limb_t divisor)
1536 {
1537   return mpn_modexact_1_odd (ptr, size, divisor);
1538 }
1539 
1540 void
1541 mpn_toom22_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
1542 {
1543   mp_ptr  tspace;
1544   TMP_DECL;
1545   TMP_MARK;
1546   tspace = TMP_ALLOC_LIMBS (mpn_toom22_mul_itch (size, size));
1547   mpn_toom22_mul (dst, src1, size, src2, size, tspace);
1548   TMP_FREE;
1549 }
1550 void
1551 mpn_toom2_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
1552 {
1553   mp_ptr tspace;
1554   TMP_DECL;
1555   TMP_MARK;
1556   tspace = TMP_ALLOC_LIMBS (mpn_toom2_sqr_itch (size));
1557   mpn_toom2_sqr (dst, src, size, tspace);
1558   TMP_FREE;
1559 }
1560 void
1561 mpn_toom33_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
1562 {
1563   mp_ptr  tspace;
1564   TMP_DECL;
1565   TMP_MARK;
1566   tspace = TMP_ALLOC_LIMBS (mpn_toom33_mul_itch (size, size));
1567   mpn_toom33_mul (dst, src1, size, src2, size, tspace);
1568   TMP_FREE;
1569 }
1570 void
1571 mpn_toom3_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
1572 {
1573   mp_ptr tspace;
1574   TMP_DECL;
1575   TMP_MARK;
1576   tspace = TMP_ALLOC_LIMBS (mpn_toom3_sqr_itch (size));
1577   mpn_toom3_sqr (dst, src, size, tspace);
1578   TMP_FREE;
1579 }
1580 void
1581 mpn_toom44_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
1582 {
1583   mp_ptr  tspace;
1584   TMP_DECL;
1585   TMP_MARK;
1586   tspace = TMP_ALLOC_LIMBS (mpn_toom44_mul_itch (size, size));
1587   mpn_toom44_mul (dst, src1, size, src2, size, tspace);
1588   TMP_FREE;
1589 }
1590 void
1591 mpn_toom4_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
1592 {
1593   mp_ptr tspace;
1594   TMP_DECL;
1595   TMP_MARK;
1596   tspace = TMP_ALLOC_LIMBS (mpn_toom4_sqr_itch (size));
1597   mpn_toom4_sqr (dst, src, size, tspace);
1598   TMP_FREE;
1599 }
1600 
1601 void
1602 mpn_toom42_mulmid_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
1603 		       mp_size_t size)
1604 {
1605   mp_ptr  tspace;
1606   mp_size_t n;
1607   TMP_DECL;
1608   TMP_MARK;
1609   tspace = TMP_ALLOC_LIMBS (mpn_toom42_mulmid_itch (size));
1610   mpn_toom42_mulmid (dst, src1, src2, size, tspace);
1611   TMP_FREE;
1612 }
1613 
1614 mp_limb_t
1615 umul_ppmm_fun (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2)
1616 {
1617   mp_limb_t  high;
1618   umul_ppmm (high, *lowptr, m1, m2);
1619   return high;
1620 }
1621 
1622 void
1623 MPN_ZERO_fun (mp_ptr ptr, mp_size_t size)
1624 { MPN_ZERO (ptr, size); }
1625 
1626 
1627 struct choice_t {
1628   const char  *name;
1629   tryfun_t    function;
1630   int         type;
1631   mp_size_t   minsize;
1632 };
1633 
1634 #if HAVE_STRINGIZE
1635 #define TRY(fun)        #fun, (tryfun_t) fun
1636 #define TRY_FUNFUN(fun) #fun, (tryfun_t) fun##_fun
1637 #else
1638 #define TRY(fun)        "fun", (tryfun_t) fun
1639 #define TRY_FUNFUN(fun) "fun", (tryfun_t) fun/**/_fun
1640 #endif
1641 
1642 const struct choice_t choice_array[] = {
1643   { TRY(mpn_add),       TYPE_ADD    },
1644   { TRY(mpn_sub),       TYPE_SUB    },
1645 
1646   { TRY(mpn_add_n),     TYPE_ADD_N  },
1647   { TRY(mpn_sub_n),     TYPE_SUB_N  },
1648 
1649 #if HAVE_NATIVE_mpn_add_nc
1650   { TRY(mpn_add_nc),    TYPE_ADD_NC },
1651 #endif
1652 #if HAVE_NATIVE_mpn_sub_nc
1653   { TRY(mpn_sub_nc),    TYPE_SUB_NC },
1654 #endif
1655 
1656 #if HAVE_NATIVE_mpn_add_n_sub_n
1657   { TRY(mpn_add_n_sub_n),  TYPE_ADDSUB_N  },
1658 #endif
1659 #if HAVE_NATIVE_mpn_add_n_sub_nc
1660   { TRY(mpn_add_n_sub_nc), TYPE_ADDSUB_NC },
1661 #endif
1662 
1663   { TRY(mpn_add_err1_n),  TYPE_ADD_ERR1_N  },
1664   { TRY(mpn_sub_err1_n),  TYPE_SUB_ERR1_N  },
1665   { TRY(mpn_add_err2_n),  TYPE_ADD_ERR2_N  },
1666   { TRY(mpn_sub_err2_n),  TYPE_SUB_ERR2_N  },
1667   { TRY(mpn_add_err3_n),  TYPE_ADD_ERR3_N  },
1668   { TRY(mpn_sub_err3_n),  TYPE_SUB_ERR3_N  },
1669 
1670   { TRY(mpn_addmul_1),  TYPE_ADDMUL_1  },
1671   { TRY(mpn_submul_1),  TYPE_SUBMUL_1  },
1672 #if HAVE_NATIVE_mpn_addmul_1c
1673   { TRY(mpn_addmul_1c), TYPE_ADDMUL_1C },
1674 #endif
1675 #if HAVE_NATIVE_mpn_submul_1c
1676   { TRY(mpn_submul_1c), TYPE_SUBMUL_1C },
1677 #endif
1678 
1679 #if HAVE_NATIVE_mpn_addmul_2
1680   { TRY(mpn_addmul_2), TYPE_ADDMUL_2, 2 },
1681 #endif
1682 #if HAVE_NATIVE_mpn_addmul_3
1683   { TRY(mpn_addmul_3), TYPE_ADDMUL_3, 3 },
1684 #endif
1685 #if HAVE_NATIVE_mpn_addmul_4
1686   { TRY(mpn_addmul_4), TYPE_ADDMUL_4, 4 },
1687 #endif
1688 #if HAVE_NATIVE_mpn_addmul_5
1689   { TRY(mpn_addmul_5), TYPE_ADDMUL_5, 5 },
1690 #endif
1691 #if HAVE_NATIVE_mpn_addmul_6
1692   { TRY(mpn_addmul_6), TYPE_ADDMUL_6, 6 },
1693 #endif
1694 #if HAVE_NATIVE_mpn_addmul_7
1695   { TRY(mpn_addmul_7), TYPE_ADDMUL_7, 7 },
1696 #endif
1697 #if HAVE_NATIVE_mpn_addmul_8
1698   { TRY(mpn_addmul_8), TYPE_ADDMUL_8, 8 },
1699 #endif
1700 
1701   { TRY_FUNFUN(mpn_com),  TYPE_COM },
1702 
1703   { TRY_FUNFUN(MPN_COPY),      TYPE_COPY },
1704   { TRY_FUNFUN(MPN_COPY_INCR), TYPE_COPYI },
1705   { TRY_FUNFUN(MPN_COPY_DECR), TYPE_COPYD },
1706 
1707   { TRY_FUNFUN(__GMPN_COPY),      TYPE_COPY },
1708 #ifdef __GMPN_COPY_INCR
1709   { TRY_FUNFUN(__GMPN_COPY_INCR), TYPE_COPYI },
1710 #endif
1711 
1712 #if HAVE_NATIVE_mpn_copyi
1713   { TRY(mpn_copyi), TYPE_COPYI },
1714 #endif
1715 #if HAVE_NATIVE_mpn_copyd
1716   { TRY(mpn_copyd), TYPE_COPYD },
1717 #endif
1718 
1719   { TRY(mpn_addcnd_n), TYPE_ADDCND_N },
1720   { TRY(mpn_subcnd_n), TYPE_SUBCND_N },
1721 #if HAVE_NATIVE_mpn_addlsh1_n
1722   { TRY(mpn_addlsh1_n), TYPE_ADDLSH1_N },
1723 #endif
1724 #if HAVE_NATIVE_mpn_addlsh2_n
1725   { TRY(mpn_addlsh2_n), TYPE_ADDLSH2_N },
1726 #endif
1727 #if HAVE_NATIVE_mpn_addlsh_n
1728   { TRY(mpn_addlsh_n), TYPE_ADDLSH_N },
1729 #endif
1730 #if HAVE_NATIVE_mpn_addlsh1_n_ip1
1731   { TRY_FUNFUN(mpn_addlsh1_n_ip1), TYPE_ADDLSH1_N_IP1 },
1732 #endif
1733 #if HAVE_NATIVE_mpn_addlsh2_n_ip1
1734   { TRY_FUNFUN(mpn_addlsh2_n_ip1), TYPE_ADDLSH2_N_IP1 },
1735 #endif
1736 #if HAVE_NATIVE_mpn_addlsh_n_ip1
1737   { TRY_FUNFUN(mpn_addlsh_n_ip1), TYPE_ADDLSH_N_IP1 },
1738 #endif
1739 #if HAVE_NATIVE_mpn_addlsh1_n_ip2
1740   { TRY_FUNFUN(mpn_addlsh1_n_ip2), TYPE_ADDLSH1_N_IP2 },
1741 #endif
1742 #if HAVE_NATIVE_mpn_addlsh2_n_ip2
1743   { TRY_FUNFUN(mpn_addlsh2_n_ip2), TYPE_ADDLSH2_N_IP2 },
1744 #endif
1745 #if HAVE_NATIVE_mpn_addlsh_n_ip2
1746   { TRY_FUNFUN(mpn_addlsh_n_ip2), TYPE_ADDLSH_N_IP2 },
1747 #endif
1748 #if HAVE_NATIVE_mpn_sublsh1_n
1749   { TRY(mpn_sublsh1_n), TYPE_SUBLSH1_N },
1750 #endif
1751 #if HAVE_NATIVE_mpn_sublsh2_n
1752   { TRY(mpn_sublsh2_n), TYPE_SUBLSH2_N },
1753 #endif
1754 #if HAVE_NATIVE_mpn_sublsh_n
1755   { TRY(mpn_sublsh_n), TYPE_SUBLSH_N },
1756 #endif
1757 #if HAVE_NATIVE_mpn_sublsh1_n_ip1
1758   { TRY_FUNFUN(mpn_sublsh1_n_ip1), TYPE_SUBLSH1_N_IP1 },
1759 #endif
1760 #if HAVE_NATIVE_mpn_sublsh2_n_ip1
1761   { TRY_FUNFUN(mpn_sublsh2_n_ip1), TYPE_SUBLSH2_N_IP1 },
1762 #endif
1763 #if HAVE_NATIVE_mpn_sublsh_n_ip1
1764   { TRY_FUNFUN(mpn_sublsh_n_ip1), TYPE_SUBLSH_N_IP1 },
1765 #endif
1766 #if HAVE_NATIVE_mpn_rsblsh1_n
1767   { TRY(mpn_rsblsh1_n), TYPE_RSBLSH1_N },
1768 #endif
1769 #if HAVE_NATIVE_mpn_rsblsh2_n
1770   { TRY(mpn_rsblsh2_n), TYPE_RSBLSH2_N },
1771 #endif
1772 #if HAVE_NATIVE_mpn_rsblsh_n
1773   { TRY(mpn_rsblsh_n), TYPE_RSBLSH_N },
1774 #endif
1775 #if HAVE_NATIVE_mpn_rsh1add_n
1776   { TRY(mpn_rsh1add_n), TYPE_RSH1ADD_N },
1777 #endif
1778 #if HAVE_NATIVE_mpn_rsh1sub_n
1779   { TRY(mpn_rsh1sub_n), TYPE_RSH1SUB_N },
1780 #endif
1781 
1782 #if HAVE_NATIVE_mpn_addlsh1_nc
1783   { TRY(mpn_addlsh1_nc), TYPE_ADDLSH1_NC },
1784 #endif
1785 #if HAVE_NATIVE_mpn_addlsh2_nc
1786   { TRY(mpn_addlsh2_nc), TYPE_ADDLSH2_NC },
1787 #endif
1788 #if HAVE_NATIVE_mpn_addlsh_nc
1789   { TRY(mpn_addlsh_nc), TYPE_ADDLSH_NC },
1790 #endif
1791 #if HAVE_NATIVE_mpn_sublsh1_nc
1792   { TRY(mpn_sublsh1_nc), TYPE_SUBLSH1_NC },
1793 #endif
1794 #if HAVE_NATIVE_mpn_sublsh2_nc
1795   { TRY(mpn_sublsh2_nc), TYPE_SUBLSH2_NC },
1796 #endif
1797 #if HAVE_NATIVE_mpn_sublsh_nc
1798   { TRY(mpn_sublsh_nc), TYPE_SUBLSH_NC },
1799 #endif
1800 #if HAVE_NATIVE_mpn_rsblsh1_nc
1801   { TRY(mpn_rsblsh1_nc), TYPE_RSBLSH1_NC },
1802 #endif
1803 #if HAVE_NATIVE_mpn_rsblsh2_nc
1804   { TRY(mpn_rsblsh2_nc), TYPE_RSBLSH2_NC },
1805 #endif
1806 #if HAVE_NATIVE_mpn_rsblsh_nc
1807   { TRY(mpn_rsblsh_nc), TYPE_RSBLSH_NC },
1808 #endif
1809 
1810   { TRY_FUNFUN(mpn_and_n),  TYPE_AND_N  },
1811   { TRY_FUNFUN(mpn_andn_n), TYPE_ANDN_N },
1812   { TRY_FUNFUN(mpn_nand_n), TYPE_NAND_N },
1813   { TRY_FUNFUN(mpn_ior_n),  TYPE_IOR_N  },
1814   { TRY_FUNFUN(mpn_iorn_n), TYPE_IORN_N },
1815   { TRY_FUNFUN(mpn_nior_n), TYPE_NIOR_N },
1816   { TRY_FUNFUN(mpn_xor_n),  TYPE_XOR_N  },
1817   { TRY_FUNFUN(mpn_xnor_n), TYPE_XNOR_N },
1818 
1819   { TRY(mpn_divrem_1),     TYPE_DIVREM_1 },
1820 #if USE_PREINV_DIVREM_1
1821   { TRY(mpn_preinv_divrem_1), TYPE_PREINV_DIVREM_1 },
1822 #endif
1823   { TRY(mpn_mod_1),        TYPE_MOD_1 },
1824 #if USE_PREINV_MOD_1
1825   { TRY(mpn_preinv_mod_1), TYPE_PREINV_MOD_1 },
1826 #endif
1827 #if HAVE_NATIVE_mpn_divrem_1c
1828   { TRY(mpn_divrem_1c),    TYPE_DIVREM_1C },
1829 #endif
1830 #if HAVE_NATIVE_mpn_mod_1c
1831   { TRY(mpn_mod_1c),       TYPE_MOD_1C },
1832 #endif
1833 #if GMP_NUMB_BITS % 4 == 0
1834   { TRY(mpn_mod_34lsub1),  TYPE_MOD_34LSUB1 },
1835 #endif
1836 
1837   { TRY_FUNFUN(udiv_qrnnd), TYPE_UDIV_QRNND, 2 },
1838 #if HAVE_NATIVE_mpn_udiv_qrnnd
1839   { TRY(mpn_udiv_qrnnd),    TYPE_UDIV_QRNND, 2 },
1840 #endif
1841 #if HAVE_NATIVE_mpn_udiv_qrnnd_r
1842   { TRY(mpn_udiv_qrnnd_r),  TYPE_UDIV_QRNND_R, 2 },
1843 #endif
1844 
1845   { TRY(mpn_divexact_1),          TYPE_DIVEXACT_1 },
1846   { TRY(mpn_bdiv_q_1),            TYPE_BDIV_Q_1 },
1847   { TRY_FUNFUN(mpn_divexact_by3), TYPE_DIVEXACT_BY3 },
1848   { TRY(mpn_divexact_by3c),       TYPE_DIVEXACT_BY3C },
1849 
1850   { TRY_FUNFUN(mpn_modexact_1_odd), TYPE_MODEXACT_1_ODD },
1851   { TRY(mpn_modexact_1c_odd),       TYPE_MODEXACT_1C_ODD },
1852 
1853 
1854   { TRY(mpn_sbpi1_div_qr), TYPE_SBPI1_DIV_QR, 3},
1855   { TRY(mpn_tdiv_qr),      TYPE_TDIV_QR },
1856 
1857   { TRY(mpn_mul_1),      TYPE_MUL_1 },
1858 #if HAVE_NATIVE_mpn_mul_1c
1859   { TRY(mpn_mul_1c),     TYPE_MUL_1C },
1860 #endif
1861 #if HAVE_NATIVE_mpn_mul_2
1862   { TRY(mpn_mul_2),      TYPE_MUL_2, 2 },
1863 #endif
1864 #if HAVE_NATIVE_mpn_mul_3
1865   { TRY(mpn_mul_3),      TYPE_MUL_3, 3 },
1866 #endif
1867 #if HAVE_NATIVE_mpn_mul_4
1868   { TRY(mpn_mul_4),      TYPE_MUL_4, 4 },
1869 #endif
1870 #if HAVE_NATIVE_mpn_mul_5
1871   { TRY(mpn_mul_5),      TYPE_MUL_5, 5 },
1872 #endif
1873 #if HAVE_NATIVE_mpn_mul_6
1874   { TRY(mpn_mul_6),      TYPE_MUL_6, 6 },
1875 #endif
1876 
1877   { TRY(mpn_rshift),     TYPE_RSHIFT },
1878   { TRY(mpn_lshift),     TYPE_LSHIFT },
1879   { TRY(mpn_lshiftc),    TYPE_LSHIFTC },
1880 
1881 
1882   { TRY(mpn_mul_basecase), TYPE_MUL_MN },
1883   { TRY(mpn_mulmid_basecase), TYPE_MULMID_MN },
1884   { TRY(mpn_mullo_basecase), TYPE_MULLO_N },
1885 #if SQR_TOOM2_THRESHOLD > 0
1886   { TRY(mpn_sqr_basecase), TYPE_SQR },
1887 #endif
1888 
1889   { TRY(mpn_mul),    TYPE_MUL_MN },
1890   { TRY(mpn_mul_n),  TYPE_MUL_N },
1891   { TRY(mpn_sqr),    TYPE_SQR },
1892 
1893   { TRY_FUNFUN(umul_ppmm), TYPE_UMUL_PPMM, 2 },
1894 #if HAVE_NATIVE_mpn_umul_ppmm
1895   { TRY(mpn_umul_ppmm),    TYPE_UMUL_PPMM, 2 },
1896 #endif
1897 #if HAVE_NATIVE_mpn_umul_ppmm_r
1898   { TRY(mpn_umul_ppmm_r),  TYPE_UMUL_PPMM_R, 2 },
1899 #endif
1900 
1901   { TRY_FUNFUN(mpn_toom22_mul),  TYPE_MUL_N,  MPN_TOOM22_MUL_MINSIZE },
1902   { TRY_FUNFUN(mpn_toom2_sqr),   TYPE_SQR,    MPN_TOOM2_SQR_MINSIZE },
1903   { TRY_FUNFUN(mpn_toom33_mul),  TYPE_MUL_N,  MPN_TOOM33_MUL_MINSIZE },
1904   { TRY_FUNFUN(mpn_toom3_sqr),   TYPE_SQR,    MPN_TOOM3_SQR_MINSIZE },
1905   { TRY_FUNFUN(mpn_toom44_mul),  TYPE_MUL_N,  MPN_TOOM44_MUL_MINSIZE },
1906   { TRY_FUNFUN(mpn_toom4_sqr),   TYPE_SQR,    MPN_TOOM4_SQR_MINSIZE },
1907 
1908   { TRY(mpn_mulmid_n),  TYPE_MULMID_N, 1 },
1909   { TRY(mpn_mulmid),  TYPE_MULMID_MN, 1 },
1910   { TRY_FUNFUN(mpn_toom42_mulmid),  TYPE_MULMID_N,
1911     (2 * MPN_TOOM42_MULMID_MINSIZE - 1) },
1912 
1913   { TRY(mpn_gcd_1),        TYPE_GCD_1            },
1914   { TRY(mpn_gcd),          TYPE_GCD              },
1915   { TRY(mpz_legendre),     TYPE_MPZ_LEGENDRE     },
1916   { TRY(mpz_jacobi),       TYPE_MPZ_JACOBI       },
1917   { TRY(mpz_kronecker),    TYPE_MPZ_KRONECKER    },
1918   { TRY(mpz_kronecker_ui), TYPE_MPZ_KRONECKER_UI },
1919   { TRY(mpz_kronecker_si), TYPE_MPZ_KRONECKER_SI },
1920   { TRY(mpz_ui_kronecker), TYPE_MPZ_UI_KRONECKER },
1921   { TRY(mpz_si_kronecker), TYPE_MPZ_SI_KRONECKER },
1922 
1923   { TRY(mpn_popcount),   TYPE_POPCOUNT },
1924   { TRY(mpn_hamdist),    TYPE_HAMDIST },
1925 
1926   { TRY(mpn_sqrtrem),    TYPE_SQRTREM },
1927 
1928   { TRY_FUNFUN(MPN_ZERO), TYPE_ZERO },
1929 
1930   { TRY(mpn_get_str),    TYPE_GET_STR },
1931 
1932   { TRY(mpn_binvert),    TYPE_BINVERT },
1933   { TRY(mpn_invert),     TYPE_INVERT  },
1934 
1935 #ifdef EXTRA_ROUTINES
1936   EXTRA_ROUTINES
1937 #endif
1938 };
1939 
1940 const struct choice_t *choice = NULL;
1941 
1942 
1943 void
1944 mprotect_maybe (void *addr, size_t len, int prot)
1945 {
1946   if (!option_redzones)
1947     return;
1948 
1949 #if HAVE_MPROTECT
1950   if (mprotect (addr, len, prot) != 0)
1951     {
1952       fprintf (stderr, "Cannot mprotect %p 0x%X 0x%X: %s\n",
1953 	       addr, (unsigned) len, prot, strerror (errno));
1954       exit (1);
1955     }
1956 #else
1957   {
1958     static int  warned = 0;
1959     if (!warned)
1960       {
1961 	fprintf (stderr,
1962 		 "mprotect not available, bounds testing not performed\n");
1963 	warned = 1;
1964       }
1965   }
1966 #endif
1967 }
1968 
1969 /* round "a" up to a multiple of "m" */
1970 size_t
1971 round_up_multiple (size_t a, size_t m)
1972 {
1973   unsigned long  r;
1974 
1975   r = a % m;
1976   if (r == 0)
1977     return a;
1978   else
1979     return a + (m - r);
1980 }
1981 
1982 
1983 /* On some systems it seems that only an mmap'ed region can be mprotect'ed,
1984    for instance HP-UX 10.
1985 
1986    mmap will almost certainly return a pointer already aligned to a page
1987    boundary, but it's easy enough to share the alignment handling with the
1988    malloc case. */
1989 
1990 void
1991 malloc_region (struct region_t *r, mp_size_t n)
1992 {
1993   mp_ptr  p;
1994   size_t  nbytes;
1995 
1996   ASSERT ((pagesize % BYTES_PER_MP_LIMB) == 0);
1997 
1998   n = round_up_multiple (n, PAGESIZE_LIMBS);
1999   r->size = n;
2000 
2001   nbytes = n*BYTES_PER_MP_LIMB + 2*REDZONE_BYTES + pagesize;
2002 
2003 #if defined (MAP_ANONYMOUS) && ! defined (MAP_ANON)
2004 #define MAP_ANON  MAP_ANONYMOUS
2005 #endif
2006 
2007 #if HAVE_MMAP && defined (MAP_ANON)
2008   /* note must pass fd=-1 for MAP_ANON on BSD */
2009   p = (mp_ptr) mmap (NULL, nbytes, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
2010   if (p == (void *) -1)
2011     {
2012       fprintf (stderr, "Cannot mmap %#x anon bytes: %s\n",
2013 	       (unsigned) nbytes, strerror (errno));
2014       exit (1);
2015     }
2016 #else
2017   p = (mp_ptr) malloc (nbytes);
2018   ASSERT_ALWAYS (p != NULL);
2019 #endif
2020 
2021   p = (mp_ptr) align_pointer (p, pagesize);
2022 
2023   mprotect_maybe (p, REDZONE_BYTES, PROT_NONE);
2024   p += REDZONE_LIMBS;
2025   r->ptr = p;
2026 
2027   mprotect_maybe (p + n, REDZONE_BYTES, PROT_NONE);
2028 }
2029 
2030 void
2031 mprotect_region (const struct region_t *r, int prot)
2032 {
2033   mprotect_maybe (r->ptr, r->size, prot);
2034 }
2035 
2036 
2037 /* First four entries must be 0,1,2,3 for the benefit of CARRY_BIT, CARRY_3,
2038    and CARRY_4 */
2039 mp_limb_t  carry_array[] = {
2040   0, 1, 2, 3,
2041   4,
2042   CNST_LIMB(1) << 8,
2043   CNST_LIMB(1) << 16,
2044   GMP_NUMB_MAX
2045 };
2046 int        carry_index;
2047 
2048 #define CARRY_COUNT                                             \
2049   ((tr->carry == CARRY_BIT) ? 2                                 \
2050    : tr->carry == CARRY_3   ? 3                                 \
2051    : tr->carry == CARRY_4   ? 4                                 \
2052    : (tr->carry == CARRY_LIMB || tr->carry == CARRY_DIVISOR)    \
2053      ? numberof(carry_array) + CARRY_RANDOMS                    \
2054    : 1)
2055 
2056 #define MPN_RANDOM_ALT(index,dst,size) \
2057   (((index) & 1) ? refmpn_random (dst, size) : refmpn_random2 (dst, size))
2058 
2059 /* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
2060    the same type */
2061 #define CARRY_ITERATION                                                 \
2062   for (carry_index = 0;                                                 \
2063        (carry_index < numberof (carry_array)                            \
2064 	? (carry = carry_array[carry_index])                            \
2065 	: (MPN_RANDOM_ALT (carry_index, &carry, 1), (mp_limb_t) 0)),    \
2066 	 (tr->carry == CARRY_DIVISOR ? carry %= divisor : 0),           \
2067 	 carry_index < CARRY_COUNT;                                     \
2068        carry_index++)
2069 
2070 
2071 mp_limb_t  multiplier_array[] = {
2072   0, 1, 2, 3,
2073   CNST_LIMB(1) << 8,
2074   CNST_LIMB(1) << 16,
2075   GMP_NUMB_MAX - 2,
2076   GMP_NUMB_MAX - 1,
2077   GMP_NUMB_MAX
2078 };
2079 int        multiplier_index;
2080 
2081 mp_limb_t  divisor_array[] = {
2082   1, 2, 3,
2083   CNST_LIMB(1) << 8,
2084   CNST_LIMB(1) << 16,
2085   CNST_LIMB(1) << (GMP_NUMB_BITS/2 - 1),
2086   GMP_NUMB_MAX >> (GMP_NUMB_BITS/2),
2087   GMP_NUMB_HIGHBIT,
2088   GMP_NUMB_HIGHBIT + 1,
2089   GMP_NUMB_MAX - 2,
2090   GMP_NUMB_MAX - 1,
2091   GMP_NUMB_MAX
2092 };
2093 
2094 int        divisor_index;
2095 
2096 /* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
2097    the same type */
2098 #define ARRAY_ITERATION(var, index, limit, array, randoms, cond)        \
2099   for (index = 0;                                                       \
2100        (index < numberof (array)                                        \
2101 	? (var = array[index])                                          \
2102 	: (MPN_RANDOM_ALT (index, &var, 1), (mp_limb_t) 0)),            \
2103        index < limit;                                                   \
2104        index++)
2105 
2106 #define MULTIPLIER_COUNT                                \
2107   (tr->multiplier                                       \
2108     ? numberof (multiplier_array) + MULTIPLIER_RANDOMS  \
2109     : 1)
2110 
2111 #define MULTIPLIER_ITERATION                                            \
2112   ARRAY_ITERATION(multiplier, multiplier_index, MULTIPLIER_COUNT,       \
2113 		  multiplier_array, MULTIPLIER_RANDOMS, TRY_MULTIPLIER)
2114 
2115 #define DIVISOR_COUNT                           \
2116   (tr->divisor                                  \
2117    ? numberof (divisor_array) + DIVISOR_RANDOMS \
2118    : 1)
2119 
2120 #define DIVISOR_ITERATION                                               \
2121   ARRAY_ITERATION(divisor, divisor_index, DIVISOR_COUNT, divisor_array, \
2122 		  DIVISOR_RANDOMS, TRY_DIVISOR)
2123 
2124 
2125 /* overlap_array[].s[i] is where s[i] should be, 0 or 1 means overlapping
2126    d[0] or d[1] respectively, -1 means a separate (write-protected)
2127    location. */
2128 
2129 struct overlap_t {
2130   int  s[NUM_SOURCES];
2131 } overlap_array[] = {
2132   { { -1, -1, -1, -1, -1 } },
2133   { {  0, -1, -1, -1, -1 } },
2134   { { -1,  0, -1, -1, -1 } },
2135   { {  0,  0, -1, -1, -1 } },
2136   { {  1, -1, -1, -1, -1 } },
2137   { { -1,  1, -1, -1, -1 } },
2138   { {  1,  1, -1, -1, -1 } },
2139   { {  0,  1, -1, -1, -1 } },
2140   { {  1,  0, -1, -1, -1 } },
2141 };
2142 
2143 struct overlap_t  *overlap, *overlap_limit;
2144 
2145 #define OVERLAP_COUNT                   \
2146   (tr->overlap & OVERLAP_NONE       ? 1 \
2147    : tr->overlap & OVERLAP_NOT_SRCS ? 3 \
2148    : tr->overlap & OVERLAP_NOT_SRC2 ? 2 \
2149    : tr->overlap & OVERLAP_NOT_DST2 ? 4	\
2150    : tr->dst[1]                     ? 9 \
2151    : tr->src[1]                     ? 4 \
2152    : tr->dst[0]                     ? 2 \
2153    : 1)
2154 
2155 #define OVERLAP_ITERATION                               \
2156   for (overlap = &overlap_array[0],                     \
2157     overlap_limit = &overlap_array[OVERLAP_COUNT];      \
2158     overlap < overlap_limit;                            \
2159     overlap++)
2160 
2161 
2162 int  base = 10;
2163 
2164 #define T_RAND_COUNT  2
2165 int  t_rand;
2166 
2167 void
2168 t_random (mp_ptr ptr, mp_size_t n)
2169 {
2170   if (n == 0)
2171     return;
2172 
2173   switch (option_data) {
2174   case DATA_TRAND:
2175     switch (t_rand) {
2176     case 0: refmpn_random (ptr, n); break;
2177     case 1: refmpn_random2 (ptr, n); break;
2178     default: abort();
2179     }
2180     break;
2181   case DATA_SEQ:
2182     {
2183       static mp_limb_t  counter = 0;
2184       mp_size_t  i;
2185       for (i = 0; i < n; i++)
2186 	ptr[i] = ++counter;
2187     }
2188     break;
2189   case DATA_ZEROS:
2190     refmpn_zero (ptr, n);
2191     break;
2192   case DATA_FFS:
2193     refmpn_fill (ptr, n, GMP_NUMB_MAX);
2194     break;
2195   case DATA_2FD:
2196     /* Special value 0x2FFF...FFFD, which divided by 3 gives 0xFFF...FFF,
2197        inducing the q1_ff special case in the mul-by-inverse part of some
2198        versions of divrem_1 and mod_1. */
2199     refmpn_fill (ptr, n, (mp_limb_t) -1);
2200     ptr[n-1] = 2;
2201     ptr[0] -= 2;
2202     break;
2203 
2204   default:
2205     abort();
2206   }
2207 }
2208 #define T_RAND_ITERATION \
2209   for (t_rand = 0; t_rand < T_RAND_COUNT; t_rand++)
2210 
2211 
2212 void
2213 print_each (const struct each_t *e)
2214 {
2215   int  i;
2216 
2217   printf ("%s %s\n", e->name, e == &ref ? tr->reference_name : choice->name);
2218   if (tr->retval)
2219     mpn_trace ("   retval", &e->retval, 1);
2220 
2221   for (i = 0; i < NUM_DESTS; i++)
2222     {
2223       if (tr->dst[i])
2224 	{
2225 	  if (tr->dst_bytes[i])
2226 	    byte_tracen ("   d[%d]", i, e->d[i].p, d[i].size);
2227 	  else
2228 	    mpn_tracen ("   d[%d]", i, e->d[i].p, d[i].size);
2229 	  printf ("        located %p\n", (void *) (e->d[i].p));
2230 	}
2231     }
2232 
2233   for (i = 0; i < NUM_SOURCES; i++)
2234     if (tr->src[i])
2235       printf ("   s[%d] located %p\n", i, (void *)  (e->s[i].p));
2236 }
2237 
2238 
2239 void
2240 print_all (void)
2241 {
2242   int  i;
2243 
2244   printf ("\n");
2245   printf ("size  %ld\n", (long) size);
2246   if (tr->size2)
2247     printf ("size2 %ld\n", (long) size2);
2248 
2249   for (i = 0; i < NUM_DESTS; i++)
2250     if (d[i].size != size)
2251       printf ("d[%d].size %ld\n", i, (long) d[i].size);
2252 
2253   if (tr->multiplier)
2254     mpn_trace ("   multiplier", &multiplier, 1);
2255   if (tr->divisor)
2256     mpn_trace ("   divisor", &divisor, 1);
2257   if (tr->shift)
2258     printf ("   shift %lu\n", shift);
2259   if (tr->carry)
2260     mpn_trace ("   carry", &carry, 1);
2261   if (tr->msize)
2262     mpn_trace ("   multiplier_N", multiplier_N, tr->msize);
2263 
2264   for (i = 0; i < NUM_DESTS; i++)
2265     if (tr->dst[i])
2266       printf ("   d[%d] %s, align %ld, size %ld\n",
2267 	      i, d[i].high ? "high" : "low",
2268 	      (long) d[i].align, (long) d[i].size);
2269 
2270   for (i = 0; i < NUM_SOURCES; i++)
2271     {
2272       if (tr->src[i])
2273 	{
2274 	  printf ("   s[%d] %s, align %ld, ",
2275 		  i, s[i].high ? "high" : "low", (long) s[i].align);
2276 	  switch (overlap->s[i]) {
2277 	  case -1:
2278 	    printf ("no overlap\n");
2279 	    break;
2280 	  default:
2281 	    printf ("==d[%d]%s\n",
2282 		    overlap->s[i],
2283 		    tr->overlap == OVERLAP_LOW_TO_HIGH ? "+a"
2284 		    : tr->overlap == OVERLAP_HIGH_TO_LOW ? "-a"
2285 		    : "");
2286 	    break;
2287 	  }
2288 	  printf ("   s[%d]=", i);
2289 	  if (tr->carry_sign && (carry & (1 << i)))
2290 	    printf ("-");
2291 	  mpn_trace (NULL, s[i].p, SRC_SIZE(i));
2292 	}
2293     }
2294 
2295   if (tr->dst0_from_src1)
2296     mpn_trace ("   d[0]", s[1].region.ptr, size);
2297 
2298   if (tr->reference)
2299     print_each (&ref);
2300   print_each (&fun);
2301 }
2302 
2303 void
2304 compare (void)
2305 {
2306   int  error = 0;
2307   int  i;
2308 
2309   if (tr->retval && ref.retval != fun.retval)
2310     {
2311       gmp_printf ("Different return values (%Mu, %Mu)\n",
2312 		  ref.retval, fun.retval);
2313       error = 1;
2314     }
2315 
2316   for (i = 0; i < NUM_DESTS; i++)
2317     {
2318       switch (tr->dst_size[i]) {
2319       case SIZE_RETVAL:
2320       case SIZE_GET_STR:
2321 	d[i].size = ref.retval;
2322 	break;
2323       }
2324     }
2325 
2326   for (i = 0; i < NUM_DESTS; i++)
2327     {
2328       if (! tr->dst[i])
2329 	continue;
2330 
2331       if (tr->dst_bytes[i])
2332 	{
2333 	  if (memcmp (ref.d[i].p, fun.d[i].p, d[i].size) != 0)
2334 	    {
2335 	      printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n",
2336 		      i,
2337 		      (long) byte_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
2338 		      (long) byte_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
2339 	      error = 1;
2340 	    }
2341 	}
2342       else
2343 	{
2344 	  if (d[i].size != 0
2345 	      && ! refmpn_equal_anynail (ref.d[i].p, fun.d[i].p, d[i].size))
2346 	    {
2347 	      printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n",
2348 		      i,
2349 		      (long) mpn_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
2350 		      (long) mpn_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
2351 	      error = 1;
2352 	    }
2353 	}
2354     }
2355 
2356   if (error)
2357     {
2358       print_all();
2359       abort();
2360     }
2361 }
2362 
2363 
2364 /* The functions are cast if the return value should be a long rather than
2365    the default mp_limb_t.  This is necessary under _LONG_LONG_LIMB.  This
2366    might not be enough if some actual calling conventions checking is
2367    implemented on a long long limb system.  */
2368 
2369 void
2370 call (struct each_t *e, tryfun_t function)
2371 {
2372   switch (choice->type) {
2373   case TYPE_ADD:
2374   case TYPE_SUB:
2375     e->retval = CALLING_CONVENTIONS (function)
2376       (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
2377     break;
2378 
2379   case TYPE_ADD_N:
2380   case TYPE_SUB_N:
2381   case TYPE_ADDLSH1_N:
2382   case TYPE_ADDLSH2_N:
2383   case TYPE_SUBLSH1_N:
2384   case TYPE_SUBLSH2_N:
2385   case TYPE_RSBLSH1_N:
2386   case TYPE_RSBLSH2_N:
2387   case TYPE_RSH1ADD_N:
2388   case TYPE_RSH1SUB_N:
2389     e->retval = CALLING_CONVENTIONS (function)
2390       (e->d[0].p, e->s[0].p, e->s[1].p, size);
2391     break;
2392   case TYPE_ADDLSH_N:
2393   case TYPE_SUBLSH_N:
2394   case TYPE_RSBLSH_N:
2395     e->retval = CALLING_CONVENTIONS (function)
2396       (e->d[0].p, e->s[0].p, e->s[1].p, size, shift);
2397     break;
2398   case TYPE_ADDLSH_NC:
2399   case TYPE_SUBLSH_NC:
2400   case TYPE_RSBLSH_NC:
2401     e->retval = CALLING_CONVENTIONS (function)
2402       (e->d[0].p, e->s[0].p, e->s[1].p, size, shift, carry);
2403     break;
2404   case TYPE_ADDLSH1_NC:
2405   case TYPE_ADDLSH2_NC:
2406   case TYPE_SUBLSH1_NC:
2407   case TYPE_SUBLSH2_NC:
2408   case TYPE_RSBLSH1_NC:
2409   case TYPE_RSBLSH2_NC:
2410   case TYPE_ADD_NC:
2411   case TYPE_SUB_NC:
2412   case TYPE_ADDCND_N:
2413   case TYPE_SUBCND_N:
2414     e->retval = CALLING_CONVENTIONS (function)
2415       (e->d[0].p, e->s[0].p, e->s[1].p, size, carry);
2416     break;
2417   case TYPE_ADD_ERR1_N:
2418   case TYPE_SUB_ERR1_N:
2419     e->retval = CALLING_CONVENTIONS (function)
2420       (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, size, carry);
2421     break;
2422   case TYPE_ADD_ERR2_N:
2423   case TYPE_SUB_ERR2_N:
2424     e->retval = CALLING_CONVENTIONS (function)
2425       (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, e->s[3].p, size, carry);
2426     break;
2427   case TYPE_ADD_ERR3_N:
2428   case TYPE_SUB_ERR3_N:
2429     e->retval = CALLING_CONVENTIONS (function)
2430       (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, e->s[3].p, e->s[4].p, size, carry);
2431     break;
2432 
2433   case TYPE_MUL_1:
2434   case TYPE_ADDMUL_1:
2435   case TYPE_SUBMUL_1:
2436     e->retval = CALLING_CONVENTIONS (function)
2437       (e->d[0].p, e->s[0].p, size, multiplier);
2438     break;
2439   case TYPE_MUL_1C:
2440   case TYPE_ADDMUL_1C:
2441   case TYPE_SUBMUL_1C:
2442     e->retval = CALLING_CONVENTIONS (function)
2443       (e->d[0].p, e->s[0].p, size, multiplier, carry);
2444     break;
2445 
2446   case TYPE_MUL_2:
2447   case TYPE_MUL_3:
2448   case TYPE_MUL_4:
2449   case TYPE_MUL_5:
2450   case TYPE_MUL_6:
2451     if (size == 1)
2452       abort ();
2453     e->retval = CALLING_CONVENTIONS (function)
2454       (e->d[0].p, e->s[0].p, size, multiplier_N);
2455     break;
2456 
2457   case TYPE_ADDMUL_2:
2458   case TYPE_ADDMUL_3:
2459   case TYPE_ADDMUL_4:
2460   case TYPE_ADDMUL_5:
2461   case TYPE_ADDMUL_6:
2462   case TYPE_ADDMUL_7:
2463   case TYPE_ADDMUL_8:
2464     if (size == 1)
2465       abort ();
2466     e->retval = CALLING_CONVENTIONS (function)
2467       (e->d[0].p, e->s[0].p, size, multiplier_N);
2468     break;
2469 
2470   case TYPE_AND_N:
2471   case TYPE_ANDN_N:
2472   case TYPE_NAND_N:
2473   case TYPE_IOR_N:
2474   case TYPE_IORN_N:
2475   case TYPE_NIOR_N:
2476   case TYPE_XOR_N:
2477   case TYPE_XNOR_N:
2478     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
2479     break;
2480 
2481   case TYPE_ADDSUB_N:
2482     e->retval = CALLING_CONVENTIONS (function)
2483       (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size);
2484     break;
2485   case TYPE_ADDSUB_NC:
2486     e->retval = CALLING_CONVENTIONS (function)
2487       (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size, carry);
2488     break;
2489 
2490   case TYPE_COPY:
2491   case TYPE_COPYI:
2492   case TYPE_COPYD:
2493   case TYPE_COM:
2494     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
2495     break;
2496 
2497   case TYPE_ADDLSH1_N_IP1:
2498   case TYPE_ADDLSH2_N_IP1:
2499   case TYPE_ADDLSH1_N_IP2:
2500   case TYPE_ADDLSH2_N_IP2:
2501   case TYPE_SUBLSH1_N_IP1:
2502   case TYPE_SUBLSH2_N_IP1:
2503   case TYPE_DIVEXACT_BY3:
2504     e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
2505     break;
2506   case TYPE_DIVEXACT_BY3C:
2507     e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size,
2508 						carry);
2509     break;
2510 
2511 
2512   case TYPE_DIVMOD_1:
2513   case TYPE_DIVEXACT_1:
2514   case TYPE_BDIV_Q_1:
2515     e->retval = CALLING_CONVENTIONS (function)
2516       (e->d[0].p, e->s[0].p, size, divisor);
2517     break;
2518   case TYPE_DIVMOD_1C:
2519     e->retval = CALLING_CONVENTIONS (function)
2520       (e->d[0].p, e->s[0].p, size, divisor, carry);
2521     break;
2522   case TYPE_DIVREM_1:
2523     e->retval = CALLING_CONVENTIONS (function)
2524       (e->d[0].p, size2, e->s[0].p, size, divisor);
2525     break;
2526   case TYPE_DIVREM_1C:
2527     e->retval = CALLING_CONVENTIONS (function)
2528       (e->d[0].p, size2, e->s[0].p, size, divisor, carry);
2529     break;
2530   case TYPE_PREINV_DIVREM_1:
2531     {
2532       mp_limb_t  dinv;
2533       unsigned   shift;
2534       shift = refmpn_count_leading_zeros (divisor);
2535       dinv = refmpn_invert_limb (divisor << shift);
2536       e->retval = CALLING_CONVENTIONS (function)
2537 	(e->d[0].p, size2, e->s[0].p, size, divisor, dinv, shift);
2538     }
2539     break;
2540   case TYPE_MOD_1:
2541   case TYPE_MODEXACT_1_ODD:
2542     e->retval = CALLING_CONVENTIONS (function)
2543       (e->s[0].p, size, divisor);
2544     break;
2545   case TYPE_MOD_1C:
2546   case TYPE_MODEXACT_1C_ODD:
2547     e->retval = CALLING_CONVENTIONS (function)
2548       (e->s[0].p, size, divisor, carry);
2549     break;
2550   case TYPE_PREINV_MOD_1:
2551     e->retval = CALLING_CONVENTIONS (function)
2552       (e->s[0].p, size, divisor, refmpn_invert_limb (divisor));
2553     break;
2554   case TYPE_MOD_34LSUB1:
2555     e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size);
2556     break;
2557 
2558   case TYPE_UDIV_QRNND:
2559     e->retval = CALLING_CONVENTIONS (function)
2560       (e->d[0].p, e->s[0].p[1], e->s[0].p[0], divisor);
2561     break;
2562   case TYPE_UDIV_QRNND_R:
2563     e->retval = CALLING_CONVENTIONS (function)
2564       (e->s[0].p[1], e->s[0].p[0], divisor, e->d[0].p);
2565     break;
2566 
2567   case TYPE_SBPI1_DIV_QR:
2568     {
2569       gmp_pi1_t dinv;
2570       invert_pi1 (dinv, e->s[1].p[size2-1], e->s[1].p[size2-2]); /* FIXME: use refinvert_pi1 */
2571       refmpn_copyi (e->d[1].p, e->s[0].p, size);        /* dividend */
2572       refmpn_fill (e->d[0].p, size-size2, 0x98765432);  /* quotient */
2573       e->retval = CALLING_CONVENTIONS (function)
2574 	(e->d[0].p, e->d[1].p, size, e->s[1].p, size2, dinv.inv32);
2575       refmpn_zero (e->d[1].p+size2, size-size2);    /* excess over remainder */
2576     }
2577     break;
2578 
2579   case TYPE_TDIV_QR:
2580     CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, 0,
2581 				    e->s[0].p, size, e->s[1].p, size2);
2582     break;
2583 
2584   case TYPE_GCD_1:
2585     /* Must have a non-zero src, but this probably isn't the best way to do
2586        it. */
2587     if (refmpn_zero_p (e->s[0].p, size))
2588       e->retval = 0;
2589     else
2590       e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor);
2591     break;
2592 
2593   case TYPE_GCD:
2594     /* Sources are destroyed, so they're saved and replaced, but a general
2595        approach to this might be better.  Note that it's still e->s[0].p and
2596        e->s[1].p that are passed, to get the desired alignments. */
2597     {
2598       mp_ptr  s0 = refmpn_malloc_limbs (size);
2599       mp_ptr  s1 = refmpn_malloc_limbs (size2);
2600       refmpn_copyi (s0, e->s[0].p, size);
2601       refmpn_copyi (s1, e->s[1].p, size2);
2602 
2603       mprotect_region (&s[0].region, PROT_READ|PROT_WRITE);
2604       mprotect_region (&s[1].region, PROT_READ|PROT_WRITE);
2605       e->retval = CALLING_CONVENTIONS (function) (e->d[0].p,
2606 						  e->s[0].p, size,
2607 						  e->s[1].p, size2);
2608       refmpn_copyi (e->s[0].p, s0, size);
2609       refmpn_copyi (e->s[1].p, s1, size2);
2610       free (s0);
2611       free (s1);
2612     }
2613     break;
2614 
2615   case TYPE_GCD_FINDA:
2616     {
2617       /* FIXME: do this with a flag */
2618       mp_limb_t  c[2];
2619       c[0] = e->s[0].p[0];
2620       c[0] += (c[0] == 0);
2621       c[1] = e->s[0].p[0];
2622       c[1] += (c[1] == 0);
2623       e->retval = CALLING_CONVENTIONS (function) (c);
2624     }
2625     break;
2626 
2627   case TYPE_MPZ_LEGENDRE:
2628   case TYPE_MPZ_JACOBI:
2629     {
2630       mpz_t  a, b;
2631       PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
2632       PTR(b) = e->s[1].p; SIZ(b) = size2;
2633       e->retval = CALLING_CONVENTIONS (function) (a, b);
2634     }
2635     break;
2636   case TYPE_MPZ_KRONECKER:
2637     {
2638       mpz_t  a, b;
2639       PTR(a) = e->s[0].p; SIZ(a) = ((carry&1)==0 ? size : -size);
2640       PTR(b) = e->s[1].p; SIZ(b) = ((carry&2)==0 ? size2 : -size2);
2641       e->retval = CALLING_CONVENTIONS (function) (a, b);
2642     }
2643     break;
2644   case TYPE_MPZ_KRONECKER_UI:
2645     {
2646       mpz_t  a;
2647       PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
2648       e->retval = CALLING_CONVENTIONS(function) (a, (unsigned long)multiplier);
2649     }
2650     break;
2651   case TYPE_MPZ_KRONECKER_SI:
2652     {
2653       mpz_t  a;
2654       PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
2655       e->retval = CALLING_CONVENTIONS (function) (a, (long) multiplier);
2656     }
2657     break;
2658   case TYPE_MPZ_UI_KRONECKER:
2659     {
2660       mpz_t  b;
2661       PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
2662       e->retval = CALLING_CONVENTIONS(function) ((unsigned long)multiplier, b);
2663     }
2664     break;
2665   case TYPE_MPZ_SI_KRONECKER:
2666     {
2667       mpz_t  b;
2668       PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
2669       e->retval = CALLING_CONVENTIONS (function) ((long) multiplier, b);
2670     }
2671     break;
2672 
2673   case TYPE_MUL_MN:
2674   case TYPE_MULMID_MN:
2675     CALLING_CONVENTIONS (function)
2676       (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
2677     break;
2678   case TYPE_MUL_N:
2679   case TYPE_MULLO_N:
2680     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
2681     break;
2682   case TYPE_MULMID_N:
2683     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p,
2684 				    (size + 1) / 2);
2685     break;
2686   case TYPE_SQR:
2687     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
2688     break;
2689 
2690   case TYPE_UMUL_PPMM:
2691     e->retval = CALLING_CONVENTIONS (function)
2692       (e->d[0].p, e->s[0].p[0], e->s[0].p[1]);
2693     break;
2694   case TYPE_UMUL_PPMM_R:
2695     e->retval = CALLING_CONVENTIONS (function)
2696       (e->s[0].p[0], e->s[0].p[1], e->d[0].p);
2697     break;
2698 
2699   case TYPE_ADDLSH_N_IP1:
2700   case TYPE_ADDLSH_N_IP2:
2701   case TYPE_SUBLSH_N_IP1:
2702   case TYPE_LSHIFT:
2703   case TYPE_LSHIFTC:
2704   case TYPE_RSHIFT:
2705     e->retval = CALLING_CONVENTIONS (function)
2706       (e->d[0].p, e->s[0].p, size, shift);
2707     break;
2708 
2709   case TYPE_POPCOUNT:
2710     e->retval = (* (unsigned long (*)(ANYARGS))
2711 		 CALLING_CONVENTIONS (function)) (e->s[0].p, size);
2712     break;
2713   case TYPE_HAMDIST:
2714     e->retval = (* (unsigned long (*)(ANYARGS))
2715 		 CALLING_CONVENTIONS (function)) (e->s[0].p, e->s[1].p, size);
2716     break;
2717 
2718   case TYPE_SQRTREM:
2719     e->retval = (* (long (*)(ANYARGS)) CALLING_CONVENTIONS (function))
2720       (e->d[0].p, e->d[1].p, e->s[0].p, size);
2721     break;
2722 
2723   case TYPE_ZERO:
2724     CALLING_CONVENTIONS (function) (e->d[0].p, size);
2725     break;
2726 
2727   case TYPE_GET_STR:
2728     {
2729       size_t  sizeinbase, fill;
2730       char    *dst;
2731       MPN_SIZEINBASE (sizeinbase, e->s[0].p, size, base);
2732       ASSERT_ALWAYS (sizeinbase <= d[0].size);
2733       fill = d[0].size - sizeinbase;
2734       if (d[0].high)
2735 	{
2736 	  memset (e->d[0].p, 0xBA, fill);
2737 	  dst = (char *) e->d[0].p + fill;
2738 	}
2739       else
2740 	{
2741 	  dst = (char *) e->d[0].p;
2742 	  memset (dst + sizeinbase, 0xBA, fill);
2743 	}
2744       if (POW2_P (base))
2745 	{
2746 	  e->retval = CALLING_CONVENTIONS (function) (dst, base,
2747 						      e->s[0].p, size);
2748 	}
2749       else
2750 	{
2751 	  refmpn_copy (e->d[1].p, e->s[0].p, size);
2752 	  e->retval = CALLING_CONVENTIONS (function) (dst, base,
2753 						      e->d[1].p, size);
2754 	}
2755       refmpn_zero (e->d[1].p, size);  /* clobbered or unused */
2756     }
2757     break;
2758 
2759  case TYPE_INVERT:
2760     {
2761       mp_ptr scratch;
2762       TMP_DECL;
2763       TMP_MARK;
2764       scratch = TMP_ALLOC_LIMBS (mpn_invert_itch (size));
2765       CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
2766       TMP_FREE;
2767     }
2768     break;
2769   case TYPE_BINVERT:
2770     {
2771       mp_ptr scratch;
2772       TMP_DECL;
2773       TMP_MARK;
2774       scratch = TMP_ALLOC_LIMBS (mpn_binvert_itch (size));
2775       CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
2776       TMP_FREE;
2777     }
2778     break;
2779 
2780 #ifdef EXTRA_CALL
2781     EXTRA_CALL
2782 #endif
2783 
2784   default:
2785     printf ("Unknown routine type %d\n", choice->type);
2786     abort ();
2787     break;
2788   }
2789 }
2790 
2791 
2792 void
2793 pointer_setup (struct each_t *e)
2794 {
2795   int  i, j;
2796 
2797   for (i = 0; i < NUM_DESTS; i++)
2798     {
2799       switch (tr->dst_size[i]) {
2800       case 0:
2801       case SIZE_RETVAL: /* will be adjusted later */
2802 	d[i].size = size;
2803 	break;
2804 
2805       case SIZE_1:
2806 	d[i].size = 1;
2807 	break;
2808       case SIZE_2:
2809 	d[i].size = 2;
2810 	break;
2811       case SIZE_3:
2812 	d[i].size = 3;
2813 	break;
2814       case SIZE_4:
2815 	d[i].size = 4;
2816 	break;
2817       case SIZE_6:
2818 	d[i].size = 6;
2819 	break;
2820 
2821       case SIZE_PLUS_1:
2822 	d[i].size = size+1;
2823 	break;
2824       case SIZE_PLUS_MSIZE_SUB_1:
2825 	d[i].size = size + tr->msize - 1;
2826 	break;
2827 
2828       case SIZE_SUM:
2829 	if (tr->size2)
2830 	  d[i].size = size + size2;
2831 	else
2832 	  d[i].size = 2*size;
2833 	break;
2834 
2835       case SIZE_SIZE2:
2836 	d[i].size = size2;
2837 	break;
2838 
2839       case SIZE_DIFF:
2840 	d[i].size = size - size2;
2841 	break;
2842 
2843       case SIZE_DIFF_PLUS_1:
2844 	d[i].size = size - size2 + 1;
2845 	break;
2846 
2847       case SIZE_DIFF_PLUS_3:
2848 	d[i].size = size - size2 + 3;
2849 	break;
2850 
2851       case SIZE_CEIL_HALF:
2852 	d[i].size = (size+1)/2;
2853 	break;
2854 
2855       case SIZE_GET_STR:
2856 	{
2857 	  mp_limb_t ff = GMP_NUMB_MAX;
2858 	  MPN_SIZEINBASE (d[i].size, &ff - (size-1), size, base);
2859 	}
2860 	break;
2861 
2862       default:
2863 	printf ("Unrecognised dst_size type %d\n", tr->dst_size[i]);
2864 	abort ();
2865       }
2866     }
2867 
2868   /* establish e->d[].p destinations */
2869   for (i = 0; i < NUM_DESTS; i++)
2870     {
2871       mp_size_t  offset = 0;
2872 
2873       /* possible room for overlapping sources */
2874       for (j = 0; j < numberof (overlap->s); j++)
2875 	if (overlap->s[j] == i)
2876 	  offset = MAX (offset, s[j].align);
2877 
2878       if (d[i].high)
2879 	{
2880 	  if (tr->dst_bytes[i])
2881 	    {
2882 	      e->d[i].p = (mp_ptr)
2883 		((char *) (e->d[i].region.ptr + e->d[i].region.size)
2884 		 - d[i].size - d[i].align);
2885 	    }
2886 	  else
2887 	    {
2888 	      e->d[i].p = e->d[i].region.ptr + e->d[i].region.size
2889 		- d[i].size - d[i].align;
2890 	      if (tr->overlap == OVERLAP_LOW_TO_HIGH)
2891 		e->d[i].p -= offset;
2892 	    }
2893 	}
2894       else
2895 	{
2896 	  if (tr->dst_bytes[i])
2897 	    {
2898 	      e->d[i].p = (mp_ptr) ((char *) e->d[i].region.ptr + d[i].align);
2899 	    }
2900 	  else
2901 	    {
2902 	      e->d[i].p = e->d[i].region.ptr + d[i].align;
2903 	      if (tr->overlap == OVERLAP_HIGH_TO_LOW)
2904 		e->d[i].p += offset;
2905 	    }
2906 	}
2907     }
2908 
2909   /* establish e->s[].p sources */
2910   for (i = 0; i < NUM_SOURCES; i++)
2911     {
2912       int  o = overlap->s[i];
2913       switch (o) {
2914       case -1:
2915 	/* no overlap */
2916 	e->s[i].p = s[i].p;
2917 	break;
2918       case 0:
2919       case 1:
2920 	/* overlap with d[o] */
2921 	if (tr->overlap == OVERLAP_HIGH_TO_LOW)
2922 	  e->s[i].p = e->d[o].p - s[i].align;
2923 	else if (tr->overlap == OVERLAP_LOW_TO_HIGH)
2924 	  e->s[i].p = e->d[o].p + s[i].align;
2925 	else if (tr->size2 == SIZE_FRACTION)
2926 	  e->s[i].p = e->d[o].p + size2;
2927 	else
2928 	  e->s[i].p = e->d[o].p;
2929 	break;
2930       default:
2931 	abort();
2932 	break;
2933       }
2934     }
2935 }
2936 
2937 
2938 void
2939 validate_fail (void)
2940 {
2941   if (tr->reference)
2942     {
2943       trap_location = TRAP_REF;
2944       call (&ref, tr->reference);
2945       trap_location = TRAP_NOWHERE;
2946     }
2947 
2948   print_all();
2949   abort();
2950 }
2951 
2952 
2953 void
2954 try_one (void)
2955 {
2956   int  i;
2957 
2958   if (option_spinner)
2959     spinner();
2960   spinner_count++;
2961 
2962   trap_location = TRAP_SETUPS;
2963 
2964   if (tr->divisor == DIVISOR_NORM)
2965     divisor |= GMP_NUMB_HIGHBIT;
2966   if (tr->divisor == DIVISOR_ODD)
2967     divisor |= 1;
2968 
2969   for (i = 0; i < NUM_SOURCES; i++)
2970     {
2971       if (s[i].high)
2972 	s[i].p = s[i].region.ptr + s[i].region.size - SRC_SIZE(i) - s[i].align;
2973       else
2974 	s[i].p = s[i].region.ptr + s[i].align;
2975     }
2976 
2977   pointer_setup (&ref);
2978   pointer_setup (&fun);
2979 
2980   ref.retval = 0x04152637;
2981   fun.retval = 0x8C9DAEBF;
2982 
2983   t_random (multiplier_N, tr->msize);
2984 
2985   for (i = 0; i < NUM_SOURCES; i++)
2986     {
2987       if (! tr->src[i])
2988 	continue;
2989 
2990       mprotect_region (&s[i].region, PROT_READ|PROT_WRITE);
2991       t_random (s[i].p, SRC_SIZE(i));
2992 
2993       switch (tr->data) {
2994       case DATA_NON_ZERO:
2995 	if (refmpn_zero_p (s[i].p, SRC_SIZE(i)))
2996 	  s[i].p[0] = 1;
2997 	break;
2998 
2999       case DATA_MULTIPLE_DIVISOR:
3000 	/* same number of low zero bits as divisor */
3001 	s[i].p[0] &= ~ LOW_ZEROS_MASK (divisor);
3002 	refmpn_sub_1 (s[i].p, s[i].p, size,
3003 		      refmpn_mod_1 (s[i].p, size, divisor));
3004 	break;
3005 
3006       case DATA_GCD:
3007 	/* s[1] no more bits than s[0] */
3008 	if (i == 1 && size2 == size)
3009 	  s[1].p[size-1] &= refmpn_msbone_mask (s[0].p[size-1]);
3010 
3011 	/* high limb non-zero */
3012 	s[i].p[SRC_SIZE(i)-1] += (s[i].p[SRC_SIZE(i)-1] == 0);
3013 
3014 	/* odd */
3015 	s[i].p[0] |= 1;
3016 	break;
3017 
3018       case DATA_SRC0_ODD:
3019 	if (i == 0)
3020 	  s[i].p[0] |= 1;
3021 	break;
3022 
3023       case DATA_SRC1_ODD:
3024 	if (i == 1)
3025 	  s[i].p[0] |= 1;
3026 	break;
3027 
3028       case DATA_SRC1_ODD_PRIME:
3029 	if (i == 1)
3030 	  {
3031 	    if (refmpn_zero_p (s[i].p+1, SRC_SIZE(i)-1)
3032 		&& s[i].p[0] <=3)
3033 	      s[i].p[0] = 3;
3034 	    else
3035 	      {
3036 		mpz_t p;
3037 		mpz_init (p);
3038 		for (;;)
3039 		  {
3040 		    _mpz_realloc (p, SRC_SIZE(i));
3041 		    MPN_COPY (PTR(p), s[i].p, SRC_SIZE(i));
3042 		    SIZ(p) = SRC_SIZE(i);
3043 		    MPN_NORMALIZE (PTR(p), SIZ(p));
3044 		    mpz_nextprime (p, p);
3045 		    if (mpz_size (p) <= SRC_SIZE(i))
3046 		      break;
3047 
3048 		    t_random (s[i].p, SRC_SIZE(i));
3049 		  }
3050 		MPN_COPY (s[i].p, PTR(p), SIZ(p));
3051 		if (SIZ(p) < SRC_SIZE(i))
3052 		  MPN_ZERO (s[i].p + SIZ(p), SRC_SIZE(i) - SIZ(p));
3053 		mpz_clear (p);
3054 	      }
3055 	  }
3056 	break;
3057 
3058       case DATA_SRC1_HIGHBIT:
3059 	if (i == 1)
3060 	  {
3061 	    if (tr->size2)
3062 	      s[i].p[size2-1] |= GMP_NUMB_HIGHBIT;
3063 	    else
3064 	      s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
3065 	  }
3066 	break;
3067 
3068       case DATA_SRC0_HIGHBIT:
3069        if (i == 0)
3070 	 {
3071 	   s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
3072 	 }
3073        break;
3074 
3075       case DATA_UDIV_QRNND:
3076 	s[i].p[1] %= divisor;
3077 	break;
3078       }
3079 
3080       mprotect_region (&s[i].region, PROT_READ);
3081     }
3082 
3083   for (i = 0; i < NUM_DESTS; i++)
3084     {
3085       if (! tr->dst[i])
3086 	continue;
3087 
3088       if (tr->dst0_from_src1 && i==0)
3089 	{
3090 	  mp_size_t  copy = MIN (d[0].size, SRC_SIZE(1));
3091 	  mp_size_t  fill = MAX (0, d[0].size - copy);
3092 	  MPN_COPY (fun.d[0].p, s[1].region.ptr, copy);
3093 	  MPN_COPY (ref.d[0].p, s[1].region.ptr, copy);
3094 	  refmpn_fill (fun.d[0].p + copy, fill, DEADVAL);
3095 	  refmpn_fill (ref.d[0].p + copy, fill, DEADVAL);
3096 	}
3097       else if (tr->dst_bytes[i])
3098 	{
3099 	  memset (ref.d[i].p, 0xBA, d[i].size);
3100 	  memset (fun.d[i].p, 0xBA, d[i].size);
3101 	}
3102       else
3103 	{
3104 	  refmpn_fill (ref.d[i].p, d[i].size, DEADVAL);
3105 	  refmpn_fill (fun.d[i].p, d[i].size, DEADVAL);
3106 	}
3107     }
3108 
3109   for (i = 0; i < NUM_SOURCES; i++)
3110     {
3111       if (! tr->src[i])
3112 	continue;
3113 
3114       if (ref.s[i].p != s[i].p)
3115 	{
3116 	  refmpn_copyi (ref.s[i].p, s[i].p, SRC_SIZE(i));
3117 	  refmpn_copyi (fun.s[i].p, s[i].p, SRC_SIZE(i));
3118 	}
3119     }
3120 
3121   if (option_print)
3122     print_all();
3123 
3124   if (tr->validate != NULL)
3125     {
3126       trap_location = TRAP_FUN;
3127       call (&fun, choice->function);
3128       trap_location = TRAP_NOWHERE;
3129 
3130       if (! CALLING_CONVENTIONS_CHECK ())
3131 	{
3132 	  print_all();
3133 	  abort();
3134 	}
3135 
3136       (*tr->validate) ();
3137     }
3138   else
3139     {
3140       trap_location = TRAP_REF;
3141       call (&ref, tr->reference);
3142       trap_location = TRAP_FUN;
3143       call (&fun, choice->function);
3144       trap_location = TRAP_NOWHERE;
3145 
3146       if (! CALLING_CONVENTIONS_CHECK ())
3147 	{
3148 	  print_all();
3149 	  abort();
3150 	}
3151 
3152       compare ();
3153     }
3154 }
3155 
3156 
3157 #define SIZE_ITERATION                                          \
3158   for (size = MAX3 (option_firstsize,                           \
3159 		    choice->minsize,                            \
3160 		    (tr->size == SIZE_ALLOW_ZERO) ? 0 : 1),	\
3161 	 size += (tr->size == SIZE_ODD) && !(size & 1);		\
3162        size <= option_lastsize;                                 \
3163        size += (tr->size == SIZE_ODD) ? 2 : 1)
3164 
3165 #define SIZE2_FIRST                                     \
3166   (tr->size2 == SIZE_2 ? 2                              \
3167    : tr->size2 == SIZE_FRACTION ? option_firstsize2     \
3168    : tr->size2 == SIZE_CEIL_HALF ? ((size + 1) / 2)	\
3169    : tr->size2 ?                                        \
3170    MAX (choice->minsize, (option_firstsize2 != 0        \
3171 			  ? option_firstsize2 : 1))     \
3172    : 0)
3173 
3174 #define SIZE2_LAST                                      \
3175   (tr->size2 == SIZE_2 ? 2                              \
3176    : tr->size2 == SIZE_FRACTION ? FRACTION_COUNT-1      \
3177    : tr->size2 == SIZE_CEIL_HALF ? ((size + 1) / 2)	\
3178    : tr->size2 ? size                                   \
3179    : 0)
3180 
3181 #define SIZE2_ITERATION \
3182   for (size2 = SIZE2_FIRST; size2 <= SIZE2_LAST; size2++)
3183 
3184 #define ALIGN_COUNT(cond)  ((cond) ? ALIGNMENTS : 1)
3185 #define ALIGN_ITERATION(w,n,cond) \
3186   for (w[n].align = 0; w[n].align < ALIGN_COUNT(cond); w[n].align++)
3187 
3188 #define HIGH_LIMIT(cond)  ((cond) != 0)
3189 #define HIGH_COUNT(cond)  (HIGH_LIMIT (cond) + 1)
3190 #define HIGH_ITERATION(w,n,cond) \
3191   for (w[n].high = 0; w[n].high <= HIGH_LIMIT(cond); w[n].high++)
3192 
3193 #define SHIFT_LIMIT                                     \
3194   ((unsigned long) (tr->shift ? GMP_NUMB_BITS -1 : 1))
3195 
3196 #define SHIFT_ITERATION                                 \
3197   for (shift = 1; shift <= SHIFT_LIMIT; shift++)
3198 
3199 
3200 void
3201 try_many (void)
3202 {
3203   int   i;
3204 
3205   {
3206     unsigned long  total = 1;
3207 
3208     total *= option_repetitions;
3209     total *= option_lastsize;
3210     if (tr->size2 == SIZE_FRACTION) total *= FRACTION_COUNT;
3211     else if (tr->size2)             total *= (option_lastsize+1)/2;
3212 
3213     total *= SHIFT_LIMIT;
3214     total *= MULTIPLIER_COUNT;
3215     total *= DIVISOR_COUNT;
3216     total *= CARRY_COUNT;
3217     total *= T_RAND_COUNT;
3218 
3219     total *= HIGH_COUNT (tr->dst[0]);
3220     total *= HIGH_COUNT (tr->dst[1]);
3221     total *= HIGH_COUNT (tr->src[0]);
3222     total *= HIGH_COUNT (tr->src[1]);
3223 
3224     total *= ALIGN_COUNT (tr->dst[0]);
3225     total *= ALIGN_COUNT (tr->dst[1]);
3226     total *= ALIGN_COUNT (tr->src[0]);
3227     total *= ALIGN_COUNT (tr->src[1]);
3228 
3229     total *= OVERLAP_COUNT;
3230 
3231     printf ("%s %lu\n", choice->name, total);
3232   }
3233 
3234   spinner_count = 0;
3235 
3236   for (i = 0; i < option_repetitions; i++)
3237     SIZE_ITERATION
3238       SIZE2_ITERATION
3239 
3240       SHIFT_ITERATION
3241       MULTIPLIER_ITERATION
3242       DIVISOR_ITERATION
3243       CARRY_ITERATION /* must be after divisor */
3244       T_RAND_ITERATION
3245 
3246       HIGH_ITERATION(d,0, tr->dst[0])
3247       HIGH_ITERATION(d,1, tr->dst[1])
3248       HIGH_ITERATION(s,0, tr->src[0])
3249       HIGH_ITERATION(s,1, tr->src[1])
3250 
3251       ALIGN_ITERATION(d,0, tr->dst[0])
3252       ALIGN_ITERATION(d,1, tr->dst[1])
3253       ALIGN_ITERATION(s,0, tr->src[0])
3254       ALIGN_ITERATION(s,1, tr->src[1])
3255 
3256       OVERLAP_ITERATION
3257       try_one();
3258 
3259   printf("\n");
3260 }
3261 
3262 
3263 /* Usually print_all() doesn't show much, but it might give a hint as to
3264    where the function was up to when it died. */
3265 void
3266 trap (int sig)
3267 {
3268   const char *name = "noname";
3269 
3270   switch (sig) {
3271   case SIGILL:  name = "SIGILL";  break;
3272 #ifdef SIGBUS
3273   case SIGBUS:  name = "SIGBUS";  break;
3274 #endif
3275   case SIGSEGV: name = "SIGSEGV"; break;
3276   case SIGFPE:  name = "SIGFPE";  break;
3277   }
3278 
3279   printf ("\n\nSIGNAL TRAP: %s\n", name);
3280 
3281   switch (trap_location) {
3282   case TRAP_REF:
3283     printf ("  in reference function: %s\n", tr->reference_name);
3284     break;
3285   case TRAP_FUN:
3286     printf ("  in test function: %s\n", choice->name);
3287     print_all ();
3288     break;
3289   case TRAP_SETUPS:
3290     printf ("  in parameter setups\n");
3291     print_all ();
3292     break;
3293   default:
3294     printf ("  somewhere unknown\n");
3295     break;
3296   }
3297   exit (1);
3298 }
3299 
3300 
3301 void
3302 try_init (void)
3303 {
3304 #if HAVE_GETPAGESIZE
3305   /* Prefer getpagesize() over sysconf(), since on SunOS 4 sysconf() doesn't
3306      know _SC_PAGESIZE. */
3307   pagesize = getpagesize ();
3308 #else
3309 #if HAVE_SYSCONF
3310   if ((pagesize = sysconf (_SC_PAGESIZE)) == -1)
3311     {
3312       /* According to the linux man page, sysconf doesn't set errno */
3313       fprintf (stderr, "Cannot get sysconf _SC_PAGESIZE\n");
3314       exit (1);
3315     }
3316 #else
3317 Error, error, cannot get page size
3318 #endif
3319 #endif
3320 
3321   printf ("pagesize is 0x%lX bytes\n", pagesize);
3322 
3323   signal (SIGILL,  trap);
3324 #ifdef SIGBUS
3325   signal (SIGBUS,  trap);
3326 #endif
3327   signal (SIGSEGV, trap);
3328   signal (SIGFPE,  trap);
3329 
3330   {
3331     int  i;
3332 
3333     for (i = 0; i < NUM_SOURCES; i++)
3334       {
3335 	malloc_region (&s[i].region, 2*option_lastsize+ALIGNMENTS-1);
3336 	printf ("s[%d] %p to %p (0x%lX bytes)\n",
3337 		i, (void *) (s[i].region.ptr),
3338 		(void *) (s[i].region.ptr + s[i].region.size),
3339 		(long) s[i].region.size * BYTES_PER_MP_LIMB);
3340       }
3341 
3342 #define INIT_EACH(e,es)                                                 \
3343     for (i = 0; i < NUM_DESTS; i++)                                     \
3344       {                                                                 \
3345 	malloc_region (&e.d[i].region, 2*option_lastsize+ALIGNMENTS-1); \
3346 	printf ("%s d[%d] %p to %p (0x%lX bytes)\n",                    \
3347 		es, i, (void *) (e.d[i].region.ptr),			\
3348 		(void *)  (e.d[i].region.ptr + e.d[i].region.size),	\
3349 		(long) e.d[i].region.size * BYTES_PER_MP_LIMB);         \
3350       }
3351 
3352     INIT_EACH(ref, "ref");
3353     INIT_EACH(fun, "fun");
3354   }
3355 }
3356 
3357 int
3358 strmatch_wild (const char *pattern, const char *str)
3359 {
3360   size_t  plen, slen;
3361 
3362   /* wildcard at start */
3363   if (pattern[0] == '*')
3364     {
3365       pattern++;
3366       plen = strlen (pattern);
3367       slen = strlen (str);
3368       return (plen == 0
3369 	      || (slen >= plen && memcmp (pattern, str+slen-plen, plen) == 0));
3370     }
3371 
3372   /* wildcard at end */
3373   plen = strlen (pattern);
3374   if (plen >= 1 && pattern[plen-1] == '*')
3375     return (memcmp (pattern, str, plen-1) == 0);
3376 
3377   /* no wildcards */
3378   return (strcmp (pattern, str) == 0);
3379 }
3380 
3381 void
3382 try_name (const char *name)
3383 {
3384   int  found = 0;
3385   int  i;
3386 
3387   for (i = 0; i < numberof (choice_array); i++)
3388     {
3389       if (strmatch_wild (name, choice_array[i].name))
3390 	{
3391 	  choice = &choice_array[i];
3392 	  tr = &param[choice->type];
3393 	  try_many ();
3394 	  found = 1;
3395 	}
3396     }
3397 
3398   if (!found)
3399     {
3400       printf ("%s unknown\n", name);
3401       /* exit (1); */
3402     }
3403 }
3404 
3405 
3406 void
3407 usage (const char *prog)
3408 {
3409   int  col = 0;
3410   int  i;
3411 
3412   printf ("Usage: %s [options] function...\n", prog);
3413   printf ("    -1        use limb data 1,2,3,etc\n");
3414   printf ("    -9        use limb data all 0xFF..FFs\n");
3415   printf ("    -a zeros  use limb data all zeros\n");
3416   printf ("    -a ffs    use limb data all 0xFF..FFs (same as -9)\n");
3417   printf ("    -a 2fd    use data 0x2FFF...FFFD\n");
3418   printf ("    -p        print each case tried (try this if seg faulting)\n");
3419   printf ("    -R        seed random numbers from time()\n");
3420   printf ("    -r reps   set repetitions (default %d)\n", DEFAULT_REPETITIONS);
3421   printf ("    -s size   starting size to test\n");
3422   printf ("    -S size2  starting size2 to test\n");
3423   printf ("    -s s1-s2  range of sizes to test\n");
3424   printf ("    -W        don't show the spinner (use this in gdb)\n");
3425   printf ("    -z        disable mprotect() redzones\n");
3426   printf ("Default data is refmpn_random() and refmpn_random2().\n");
3427   printf ("\n");
3428   printf ("Functions that can be tested:\n");
3429 
3430   for (i = 0; i < numberof (choice_array); i++)
3431     {
3432       if (col + 1 + strlen (choice_array[i].name) > 79)
3433 	{
3434 	  printf ("\n");
3435 	  col = 0;
3436 	}
3437       printf (" %s", choice_array[i].name);
3438       col += 1 + strlen (choice_array[i].name);
3439     }
3440   printf ("\n");
3441 
3442   exit(1);
3443 }
3444 
3445 
3446 int
3447 main (int argc, char *argv[])
3448 {
3449   int  i;
3450 
3451   /* unbuffered output */
3452   setbuf (stdout, NULL);
3453   setbuf (stderr, NULL);
3454 
3455   /* default trace in hex, and in upper-case so can paste into bc */
3456   mp_trace_base = -16;
3457 
3458   param_init ();
3459 
3460   {
3461     unsigned long  seed = 123;
3462     int   opt;
3463 
3464     while ((opt = getopt(argc, argv, "19a:b:E:pRr:S:s:Wz")) != EOF)
3465       {
3466 	switch (opt) {
3467 	case '1':
3468 	  /* use limb data values 1, 2, 3, ... etc */
3469 	  option_data = DATA_SEQ;
3470 	  break;
3471 	case '9':
3472 	  /* use limb data values 0xFFF...FFF always */
3473 	  option_data = DATA_FFS;
3474 	  break;
3475 	case 'a':
3476 	  if (strcmp (optarg, "zeros") == 0)     option_data = DATA_ZEROS;
3477 	  else if (strcmp (optarg, "seq") == 0)  option_data = DATA_SEQ;
3478 	  else if (strcmp (optarg, "ffs") == 0)  option_data = DATA_FFS;
3479 	  else if (strcmp (optarg, "2fd") == 0)  option_data = DATA_2FD;
3480 	  else
3481 	    {
3482 	      fprintf (stderr, "unrecognised data option: %s\n", optarg);
3483 	      exit (1);
3484 	    }
3485 	  break;
3486 	case 'b':
3487 	  mp_trace_base = atoi (optarg);
3488 	  break;
3489 	case 'E':
3490 	  /* re-seed */
3491 	  sscanf (optarg, "%lu", &seed);
3492 	  printf ("Re-seeding with %lu\n", seed);
3493 	  break;
3494 	case 'p':
3495 	  option_print = 1;
3496 	  break;
3497 	case 'R':
3498 	  /* randomize */
3499 	  seed = time (NULL);
3500 	  printf ("Seeding with %lu, re-run using \"-E %lu\"\n", seed, seed);
3501 	  break;
3502 	case 'r':
3503 	  option_repetitions = atoi (optarg);
3504 	  break;
3505 	case 's':
3506 	  {
3507 	    char  *p;
3508 	    option_firstsize = strtol (optarg, 0, 0);
3509 	    if ((p = strchr (optarg, '-')) != NULL)
3510 	      option_lastsize = strtol (p+1, 0, 0);
3511 	  }
3512 	  break;
3513 	case 'S':
3514 	  /* -S <size> sets the starting size for the second of a two size
3515 	     routine (like mpn_mul_basecase) */
3516 	  option_firstsize2 = strtol (optarg, 0, 0);
3517 	  break;
3518 	case 'W':
3519 	  /* use this when running in the debugger */
3520 	  option_spinner = 0;
3521 	  break;
3522 	case 'z':
3523 	  /* disable redzones */
3524 	  option_redzones = 0;
3525 	  break;
3526 	case '?':
3527 	  usage (argv[0]);
3528 	  break;
3529 	}
3530       }
3531 
3532     gmp_randinit_default (__gmp_rands);
3533     __gmp_rands_initialized = 1;
3534     gmp_randseed_ui (__gmp_rands, seed);
3535   }
3536 
3537   try_init();
3538 
3539   if (argc <= optind)
3540     usage (argv[0]);
3541 
3542   for (i = optind; i < argc; i++)
3543     try_name (argv[i]);
3544 
3545   return 0;
3546 }
3547