try.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:73k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Run some tests on various mpn routines.
  2.    THIS IS A TEST PROGRAM USED ONLY FOR DEVELOPMENT.  IT'S ALMOST CERTAIN TO
  3.    BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE VERSIONS OF GMP.
  4. Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Free Software
  5. Foundation, Inc.
  6. This file is part of the GNU MP Library.
  7. The GNU MP Library is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU Lesser General Public License as published by
  9. the Free Software Foundation; either version 3 of the License, or (at your
  10. option) any later version.
  11. The GNU MP Library is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  13. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  14. License for more details.
  15. You should have received a copy of the GNU Lesser General Public License
  16. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  17. /* Usage: try [options] <function>...
  18.    For example, "./try mpn_add_n" to run tests of that function.
  19.    Combinations of alignments and overlaps are tested, with redzones above
  20.    or below the destinations, and with the sources write-protected.
  21.    The number of tests performed becomes ridiculously large with all the
  22.    combinations, and for that reason this can't be a part of a "make check",
  23.    it's meant only for development.  The code isn't very pretty either.
  24.    During development it can help to disable the redzones, since seeing the
  25.    rest of the destination written can show where the wrong part is, or if
  26.    the dst pointers are off by 1 or whatever.  The magic DEADVAL initial
  27.    fill (see below) will show locations never written.
  28.    The -s option can be used to test only certain size operands, which is
  29.    useful if some new code doesn't yet support say sizes less than the
  30.    unrolling, or whatever.
  31.    When a problem occurs it'll of course be necessary to run the program
  32.    under gdb to find out quite where, how and why it's going wrong.  Disable
  33.    the spinner with the -W option when doing this, or single stepping won't
  34.    work.  Using the "-1" option to run with simple data can be useful.
  35.    New functions to test can be added in try_array[].  If a new TYPE is
  36.    required then add it to the existing constants, set up its parameters in
  37.    param_init(), and add it to the call() function.  Extra parameter fields
  38.    can be added if necessary, or further interpretations given to existing
  39.    fields.
  40.    Portability:
  41.    This program is not designed for use on Cray vector systems under Unicos,
  42.    it will fail to compile due to missing _SC_PAGE_SIZE.  Those systems
  43.    don't really have pages or mprotect.  We could arrange to run the tests
  44.    without the redzones, but we haven't bothered currently.
  45.    Enhancements:
  46.    umul_ppmm support is not very good, lots of source data is generated
  47.    whereas only two limbs are needed.
  48.    Make a little scheme for interpreting the "SIZE" selections uniformly.
  49.    Make tr->size==SIZE_2 work, for the benefit of find_a which wants just 2
  50.    source limbs.  Possibly increase the default repetitions in that case.
  51.    Automatically detect gdb and disable the spinner (use -W for now).
  52.    Make a way to re-run a failing case in the debugger.  Have an option to
  53.    snapshot each test case before it's run so the data is available if a
  54.    segv occurs.  (This should be more reliable than the current print_all()
  55.    in the signal handler.)
  56.    When alignment means a dst isn't hard against the redzone, check the
  57.    space in between remains unchanged.
  58.    When a source overlaps a destination, don't run both s[i].high 0 and 1,
  59.    as s[i].high has no effect.  Maybe encode s[i].high into overlap->s[i].
  60.    When partial overlaps aren't done, don't loop over source alignments
  61.    during overlaps.
  62.    Try to make the looping code a bit less horrible.  Right now it's pretty
  63.    hard to see what iterations are actually done.
  64.    Perhaps specific setups and loops for each style of function under test
  65.    would be clearer than a parameterized general loop.  There's lots of
  66.    stuff common to all functions, but the exceptions get messy.
  67.    When there's no overlap, run with both src>dst and src<dst.  A subtle
  68.    calling-conventions violation occurred in a P6 copy which depended on the
  69.    relative location of src and dst.
  70.    multiplier_N is more or less a third source region for the addmul_N
  71.    routines, and could be done with the redzoned region scheme.
  72. */
  73. /* always do assertion checking */
  74. #define WANT_ASSERT 1
  75. #include "config.h"
  76. #include <errno.h>
  77. #include <limits.h>
  78. #include <signal.h>
  79. #include <stdio.h>
  80. #include <stdlib.h>
  81. #include <string.h>
  82. #include <time.h>
  83. #if HAVE_UNISTD_H
  84. #include <unistd.h>
  85. #endif
  86. #if HAVE_SYS_MMAN_H
  87. #include <sys/mman.h>
  88. #endif
  89. #include "gmp.h"
  90. #include "gmp-impl.h"
  91. #include "longlong.h"
  92. #include "tests.h"
  93. #if !HAVE_DECL_OPTARG
  94. extern char *optarg;
  95. extern int optind, opterr;
  96. #endif
  97. #if ! HAVE_DECL_SYS_NERR
  98. extern int sys_nerr;
  99. #endif
  100. #if ! HAVE_DECL_SYS_ERRLIST
  101. extern char *sys_errlist[];
  102. #endif
  103. #if ! HAVE_STRERROR
  104. char *
  105. strerror (int n)
  106. {
  107.   if (n < 0 || n >= sys_nerr)
  108.     return "errno out of range";
  109.   else
  110.     return sys_errlist[n];
  111. }
  112. #endif
  113. /* Rumour has it some systems lack a define of PROT_NONE. */
  114. #ifndef PROT_NONE
  115. #define PROT_NONE   0
  116. #endif
  117. /* Dummy defines for when mprotect doesn't exist. */
  118. #ifndef PROT_READ
  119. #define PROT_READ   0
  120. #endif
  121. #ifndef PROT_WRITE
  122. #define PROT_WRITE  0
  123. #endif
  124. /* _SC_PAGESIZE is standard, but hpux 9 and possibly other systems have
  125.    _SC_PAGE_SIZE instead. */
  126. #if defined (_SC_PAGE_SIZE) && ! defined (_SC_PAGESIZE)
  127. #define _SC_PAGESIZE  _SC_PAGE_SIZE
  128. #endif
  129. #ifdef EXTRA_PROTOS
  130. EXTRA_PROTOS
  131. #endif
  132. #ifdef EXTRA_PROTOS2
  133. EXTRA_PROTOS2
  134. #endif
  135. #define DEFAULT_REPETITIONS  10
  136. int  option_repetitions = DEFAULT_REPETITIONS;
  137. int  option_spinner = 1;
  138. int  option_redzones = 1;
  139. int  option_firstsize = 0;
  140. int  option_lastsize = 500;
  141. int  option_firstsize2 = 0;
  142. #define ALIGNMENTS          4
  143. #define OVERLAPS            4
  144. #define CARRY_RANDOMS       5
  145. #define MULTIPLIER_RANDOMS  5
  146. #define DIVISOR_RANDOMS     5
  147. #define FRACTION_COUNT      4
  148. int  option_print = 0;
  149. #define DATA_TRAND  0
  150. #define DATA_ZEROS  1
  151. #define DATA_SEQ    2
  152. #define DATA_FFS    3
  153. #define DATA_2FD    4
  154. int  option_data = DATA_TRAND;
  155. mp_size_t  pagesize;
  156. #define PAGESIZE_LIMBS  (pagesize / BYTES_PER_MP_LIMB)
  157. /* must be a multiple of the page size */
  158. #define REDZONE_BYTES   (pagesize * 16)
  159. #define REDZONE_LIMBS   (REDZONE_BYTES / BYTES_PER_MP_LIMB)
  160. #define MAX3(x,y,z)   (MAX (x, MAX (y, z)))
  161. #if GMP_LIMB_BITS == 32
  162. #define DEADVAL  CNST_LIMB(0xDEADBEEF)
  163. #else
  164. #define DEADVAL  CNST_LIMB(0xDEADBEEFBADDCAFE)
  165. #endif
  166. struct region_t {
  167.   mp_ptr     ptr;
  168.   mp_size_t  size;
  169. };
  170. #define TRAP_NOWHERE 0
  171. #define TRAP_REF     1
  172. #define TRAP_FUN     2
  173. #define TRAP_SETUPS  3
  174. int trap_location = TRAP_NOWHERE;
  175. #define NUM_SOURCES  2
  176. #define NUM_DESTS    2
  177. struct source_t {
  178.   struct region_t  region;
  179.   int        high;
  180.   mp_size_t  align;
  181.   mp_ptr     p;
  182. };
  183. struct source_t  s[NUM_SOURCES];
  184. struct dest_t {
  185.   int        high;
  186.   mp_size_t  align;
  187.   mp_size_t  size;
  188. };
  189. struct dest_t  d[NUM_DESTS];
  190. struct source_each_t {
  191.   mp_ptr     p;
  192. };
  193. struct dest_each_t {
  194.   struct region_t  region;
  195.   mp_ptr     p;
  196. };
  197. mp_size_t       size;
  198. mp_size_t       size2;
  199. unsigned long   shift;
  200. mp_limb_t       carry;
  201. mp_limb_t       divisor;
  202. mp_limb_t       multiplier;
  203. mp_limb_t       multiplier_N[8];
  204. struct each_t {
  205.   const char  *name;
  206.   struct dest_each_t    d[NUM_DESTS];
  207.   struct source_each_t  s[NUM_SOURCES];
  208.   mp_limb_t  retval;
  209. };
  210. struct each_t  ref = { "Ref" };
  211. struct each_t  fun = { "Fun" };
  212. #define SRC_SIZE(n)  ((n) == 1 && tr->size2 ? size2 : size)
  213. void validate_fail __GMP_PROTO ((void));
  214. #if HAVE_TRY_NEW_C
  215. #include "try-new.c"
  216. #endif
  217. typedef mp_limb_t (*tryfun_t) __GMP_PROTO ((ANYARGS));
  218. struct try_t {
  219.   char  retval;
  220.   char  src[2];
  221.   char  dst[2];
  222. #define SIZE_YES          1
  223. #define SIZE_ALLOW_ZERO   2
  224. #define SIZE_1            3  /* 1 limb  */
  225. #define SIZE_2            4  /* 2 limbs */
  226. #define SIZE_3            5  /* 3 limbs */
  227. #define SIZE_FRACTION     6  /* size2 is fraction for divrem etc */
  228. #define SIZE_SIZE2        7
  229. #define SIZE_PLUS_1       8
  230. #define SIZE_SUM          9
  231. #define SIZE_DIFF        10
  232. #define SIZE_DIFF_PLUS_1 11
  233. #define SIZE_RETVAL      12
  234. #define SIZE_CEIL_HALF   13
  235. #define SIZE_GET_STR     14
  236. #define SIZE_PLUS_MSIZE_SUB_1 15  /* size+msize-1 */
  237.   char  size;
  238.   char  size2;
  239.   char  dst_size[2];
  240.   /* multiplier_N size in limbs */
  241.   mp_size_t  msize;
  242.   char  dst_bytes[2];
  243.   char  dst0_from_src1;
  244. #define CARRY_BIT     1  /* single bit 0 or 1 */
  245. #define CARRY_3       2  /* 0, 1, 2 */
  246. #define CARRY_4       3  /* 0 to 3 */
  247. #define CARRY_LIMB    4  /* any limb value */
  248. #define CARRY_DIVISOR 5  /* carry<divisor */
  249.   char  carry;
  250.   /* a fudge to tell the output when to print negatives */
  251.   char  carry_sign;
  252.   char  multiplier;
  253.   char  shift;
  254. #define DIVISOR_LIMB  1
  255. #define DIVISOR_NORM  2
  256. #define DIVISOR_ODD   3
  257.   char  divisor;
  258. #define DATA_NON_ZERO         1
  259. #define DATA_GCD              2
  260. #define DATA_SRC0_ODD         3
  261. #define DATA_SRC0_HIGHBIT     4
  262. #define DATA_SRC1_ODD         5
  263. #define DATA_SRC1_HIGHBIT     6
  264. #define DATA_MULTIPLE_DIVISOR 7
  265. #define DATA_UDIV_QRNND       8
  266.   char  data;
  267. /* Default is allow full overlap. */
  268. #define OVERLAP_NONE         1
  269. #define OVERLAP_LOW_TO_HIGH  2
  270. #define OVERLAP_HIGH_TO_LOW  3
  271. #define OVERLAP_NOT_SRCS     4
  272. #define OVERLAP_NOT_SRC2     8
  273.   char  overlap;
  274.   tryfun_t    reference;
  275.   const char  *reference_name;
  276.   void        (*validate) __GMP_PROTO ((void));
  277.   const char  *validate_name;
  278. };
  279. struct try_t  *tr;
  280. void
  281. validate_mod_34lsub1 (void)
  282. {
  283. #define CNST_34LSUB1   ((CNST_LIMB(1) << (3 * (GMP_NUMB_BITS / 4))) - 1)
  284.   mp_srcptr  ptr = s[0].p;
  285.   int        error = 0;
  286.   mp_limb_t  got, got_mod, want, want_mod;
  287.   ASSERT (size >= 1);
  288.   got = fun.retval;
  289.   got_mod = got % CNST_34LSUB1;
  290.   want = refmpn_mod_34lsub1 (ptr, size);
  291.   want_mod = want % CNST_34LSUB1;
  292.   if (got_mod != want_mod)
  293.     {
  294.       gmp_printf ("got   0x%MX reduced from 0x%MXn", got_mod, got);
  295.       gmp_printf ("want  0x%MX reduced from 0x%MXn", want_mod, want);
  296.       error = 1;
  297.     }
  298.   if (error)
  299.     validate_fail ();
  300. }
  301. void
  302. validate_divexact_1 (void)
  303. {
  304.   mp_srcptr  src = s[0].p;
  305.   mp_srcptr  dst = fun.d[0].p;
  306.   int  error = 0;
  307.   ASSERT (size >= 1);
  308.   {
  309.     mp_ptr     tp = refmpn_malloc_limbs (size);
  310.     mp_limb_t  rem;
  311.     rem = refmpn_divrem_1 (tp, 0, src, size, divisor);
  312.     if (rem != 0)
  313.       {
  314. gmp_printf ("Remainder a%%d == 0x%MX, mpn_divexact_1 undefinedn", rem);
  315. error = 1;
  316.       }
  317.     if (! refmpn_equal_anynail (tp, dst, size))
  318.       {
  319. printf ("Quotient a/d wrongn");
  320. mpn_trace ("fun ", dst, size);
  321. mpn_trace ("want", tp, size);
  322. error = 1;
  323.       }
  324.     free (tp);
  325.   }
  326.   if (error)
  327.     validate_fail ();
  328. }
  329. void
  330. validate_modexact_1c_odd (void)
  331. {
  332.   mp_srcptr  ptr = s[0].p;
  333.   mp_limb_t  r = fun.retval;
  334.   int  error = 0;
  335.   ASSERT (size >= 1);
  336.   ASSERT (divisor & 1);
  337.   if ((r & GMP_NAIL_MASK) != 0)
  338.     printf ("r has non-zero nailn");
  339.   if (carry < divisor)
  340.     {
  341.       if (! (r < divisor))
  342. {
  343.   printf ("Don't have r < divisorn");
  344.   error = 1;
  345. }
  346.     }
  347.   else /* carry >= divisor */
  348.     {
  349.       if (! (r <= divisor))
  350. {
  351.   printf ("Don't have r <= divisorn");
  352.   error = 1;
  353. }
  354.     }
  355.   {
  356.     mp_limb_t  c = carry % divisor;
  357.     mp_ptr     tp = refmpn_malloc_limbs (size+1);
  358.     mp_size_t  k;
  359.     for (k = size-1; k <= size; k++)
  360.       {
  361. /* set {tp,size+1} to r*b^k + a - c */
  362. refmpn_copyi (tp, ptr, size);
  363. tp[size] = 0;
  364. ASSERT_NOCARRY (refmpn_add_1 (tp+k, tp+k, size+1-k, r));
  365. if (refmpn_sub_1 (tp, tp, size+1, c))
  366.   ASSERT_CARRY (mpn_add_1 (tp, tp, size+1, divisor));
  367. if (refmpn_mod_1 (tp, size+1, divisor) == 0)
  368.   goto good_remainder;
  369.       }
  370.     printf ("Remainder matches neither r*b^(size-1) nor r*b^sizen");
  371.     error = 1;
  372.   good_remainder:
  373.     free (tp);
  374.   }
  375.   if (error)
  376.     validate_fail ();
  377. }
  378. void
  379. validate_modexact_1_odd (void)
  380. {
  381.   carry = 0;
  382.   validate_modexact_1c_odd ();
  383. }
  384. void
  385. validate_sqrtrem (void)
  386. {
  387.   mp_srcptr  orig_ptr = s[0].p;
  388.   mp_size_t  orig_size = size;
  389.   mp_size_t  root_size = (size+1)/2;
  390.   mp_srcptr  root_ptr = fun.d[0].p;
  391.   mp_size_t  rem_size = fun.retval;
  392.   mp_srcptr  rem_ptr = fun.d[1].p;
  393.   mp_size_t  prod_size = 2*root_size;
  394.   mp_ptr     p;
  395.   int  error = 0;
  396.   if (rem_size < 0 || rem_size > size)
  397.     {
  398.       printf ("Bad remainder size retval %ldn", (long) rem_size);
  399.       validate_fail ();
  400.     }
  401.   p = refmpn_malloc_limbs (prod_size);
  402.   p[root_size] = refmpn_lshift (p, root_ptr, root_size, 1);
  403.   if (refmpn_cmp_twosizes (p,root_size+1, rem_ptr,rem_size) < 0)
  404.     {
  405.       printf ("Remainder bigger than 2*rootn");
  406.       error = 1;
  407.     }
  408.   refmpn_sqr (p, root_ptr, root_size);
  409.   if (rem_size != 0)
  410.     refmpn_add (p, p, prod_size, rem_ptr, rem_size);
  411.   if (refmpn_cmp_twosizes (p,prod_size, orig_ptr,orig_size) != 0)
  412.     {
  413.       printf ("root^2+rem != originaln");
  414.       mpn_trace ("prod", p, prod_size);
  415.       error = 1;
  416.     }
  417.   free (p);
  418.   if (error)
  419.     validate_fail ();
  420. }
  421. /* These types are indexes into the param[] array and are arbitrary so long
  422.    as they're all distinct and within the size of param[].  Renumber
  423.    whenever necessary or desired.  */
  424. #define TYPE_ADD               1
  425. #define TYPE_ADD_N             2
  426. #define TYPE_ADD_NC            3
  427. #define TYPE_SUB               4
  428. #define TYPE_SUB_N             5
  429. #define TYPE_SUB_NC            6
  430. #define TYPE_MUL_1             7
  431. #define TYPE_MUL_1C            8
  432. #define TYPE_MUL_2             9
  433. #define TYPE_MUL_3             92
  434. #define TYPE_MUL_4             93
  435. #define TYPE_ADDMUL_1         10
  436. #define TYPE_ADDMUL_1C        11
  437. #define TYPE_SUBMUL_1         12
  438. #define TYPE_SUBMUL_1C        13
  439. #define TYPE_ADDMUL_2         14
  440. #define TYPE_ADDMUL_3         15
  441. #define TYPE_ADDMUL_4         16
  442. #define TYPE_ADDMUL_5         17
  443. #define TYPE_ADDMUL_6         18
  444. #define TYPE_ADDMUL_7         19
  445. #define TYPE_ADDMUL_8         20
  446. #define TYPE_ADDSUB_N         21
  447. #define TYPE_ADDSUB_NC        22
  448. #define TYPE_RSHIFT           23
  449. #define TYPE_LSHIFT           24
  450. #define TYPE_LSHIFTC          25
  451. #define TYPE_COPY             26
  452. #define TYPE_COPYI            27
  453. #define TYPE_COPYD            28
  454. #define TYPE_COM              29
  455. #define TYPE_ADDLSH1_N        30
  456. #define TYPE_ADDLSH2_N        48
  457. #define TYPE_ADDLSH_N         49
  458. #define TYPE_SUBLSH1_N        31
  459. #define TYPE_SUBLSH_N        130
  460. #define TYPE_RSBLSH1_N        34
  461. #define TYPE_RSBLSH2_N        46
  462. #define TYPE_RSBLSH_N         47
  463. #define TYPE_RSH1ADD_N        32
  464. #define TYPE_RSH1SUB_N        33
  465. #define TYPE_MOD_1            35
  466. #define TYPE_MOD_1C           36
  467. #define TYPE_DIVMOD_1         37
  468. #define TYPE_DIVMOD_1C        38
  469. #define TYPE_DIVREM_1         39
  470. #define TYPE_DIVREM_1C        40
  471. #define TYPE_PREINV_DIVREM_1  41
  472. #define TYPE_PREINV_MOD_1     42
  473. #define TYPE_MOD_34LSUB1      43
  474. #define TYPE_UDIV_QRNND       44
  475. #define TYPE_UDIV_QRNND_R     45
  476. #define TYPE_DIVEXACT_1       50
  477. #define TYPE_DIVEXACT_BY3     51
  478. #define TYPE_DIVEXACT_BY3C    52
  479. #define TYPE_MODEXACT_1_ODD   53
  480. #define TYPE_MODEXACT_1C_ODD  54
  481. #define TYPE_INVERT           55
  482. #define TYPE_BINVERT          56
  483. #define TYPE_GCD              60
  484. #define TYPE_GCD_1            61
  485. #define TYPE_GCD_FINDA        62
  486. #define TYPE_MPZ_JACOBI       63
  487. #define TYPE_MPZ_KRONECKER    64
  488. #define TYPE_MPZ_KRONECKER_UI 65
  489. #define TYPE_MPZ_KRONECKER_SI 66
  490. #define TYPE_MPZ_UI_KRONECKER 67
  491. #define TYPE_MPZ_SI_KRONECKER 68
  492. #define TYPE_AND_N            70
  493. #define TYPE_NAND_N           71
  494. #define TYPE_ANDN_N           72
  495. #define TYPE_IOR_N            73
  496. #define TYPE_IORN_N           74
  497. #define TYPE_NIOR_N           75
  498. #define TYPE_XOR_N            76
  499. #define TYPE_XNOR_N           77
  500. #define TYPE_MUL_MN           80
  501. #define TYPE_MUL_N            81
  502. #define TYPE_SQR              82
  503. #define TYPE_UMUL_PPMM        83
  504. #define TYPE_UMUL_PPMM_R      84
  505. #define TYPE_MULLO_N          85
  506. #define TYPE_SBPI1_DIV_QR     90
  507. #define TYPE_TDIV_QR          91
  508. #define TYPE_SQRTREM          100
  509. #define TYPE_ZERO             101
  510. #define TYPE_GET_STR          102
  511. #define TYPE_POPCOUNT         103
  512. #define TYPE_HAMDIST          104
  513. #define TYPE_EXTRA            110
  514. struct try_t  param[150];
  515. void
  516. param_init (void)
  517. {
  518.   struct try_t  *p;
  519. #define COPY(index)  memcpy (p, &param[index], sizeof (*p))
  520. #if HAVE_STRINGIZE
  521. #define REFERENCE(fun)                  
  522.   p->reference = (tryfun_t) fun;        
  523.   p->reference_name = #fun
  524. #define VALIDATE(fun)           
  525.   p->validate = fun;            
  526.   p->validate_name = #fun
  527. #else
  528. #define REFERENCE(fun)                  
  529.   p->reference = (tryfun_t) fun;        
  530.   p->reference_name = "fun"
  531. #define VALIDATE(fun)           
  532.   p->validate = fun;            
  533.   p->validate_name = "fun"
  534. #endif
  535.   p = &param[TYPE_ADD_N];
  536.   p->retval = 1;
  537.   p->dst[0] = 1;
  538.   p->src[0] = 1;
  539.   p->src[1] = 1;
  540.   REFERENCE (refmpn_add_n);
  541.   p = &param[TYPE_ADD_NC];
  542.   COPY (TYPE_ADD_N);
  543.   p->carry = CARRY_BIT;
  544.   REFERENCE (refmpn_add_nc);
  545.   p = &param[TYPE_SUB_N];
  546.   COPY (TYPE_ADD_N);
  547.   REFERENCE (refmpn_sub_n);
  548.   p = &param[TYPE_SUB_NC];
  549.   COPY (TYPE_ADD_NC);
  550.   REFERENCE (refmpn_sub_nc);
  551.   p = &param[TYPE_ADD];
  552.   COPY (TYPE_ADD_N);
  553.   p->size = SIZE_ALLOW_ZERO;
  554.   p->size2 = 1;
  555.   REFERENCE (refmpn_add);
  556.   p = &param[TYPE_SUB];
  557.   COPY (TYPE_ADD);
  558.   REFERENCE (refmpn_sub);
  559.   p = &param[TYPE_MUL_1];
  560.   p->retval = 1;
  561.   p->dst[0] = 1;
  562.   p->src[0] = 1;
  563.   p->multiplier = 1;
  564.   p->overlap = OVERLAP_LOW_TO_HIGH;
  565.   REFERENCE (refmpn_mul_1);
  566.   p = &param[TYPE_MUL_1C];
  567.   COPY (TYPE_MUL_1);
  568.   p->carry = CARRY_LIMB;
  569.   REFERENCE (refmpn_mul_1c);
  570.   p = &param[TYPE_MUL_2];
  571.   p->retval = 1;
  572.   p->dst[0] = 1;
  573.   p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
  574.   p->src[0] = 1;
  575.   p->src[1] = 1;
  576.   p->msize = 2;
  577.   p->overlap = OVERLAP_NOT_SRC2;
  578.   REFERENCE (refmpn_mul_2);
  579.   p = &param[TYPE_MUL_3];
  580.   COPY (TYPE_MUL_2);
  581.   p->msize = 3;
  582.   REFERENCE (refmpn_mul_3);
  583.   p = &param[TYPE_MUL_4];
  584.   COPY (TYPE_MUL_2);
  585.   p->msize = 4;
  586.   REFERENCE (refmpn_mul_4);
  587.   p = &param[TYPE_ADDMUL_1];
  588.   p->retval = 1;
  589.   p->dst[0] = 1;
  590.   p->src[0] = 1;
  591.   p->multiplier = 1;
  592.   p->dst0_from_src1 = 1;
  593.   REFERENCE (refmpn_addmul_1);
  594.   p = &param[TYPE_ADDMUL_1C];
  595.   COPY (TYPE_ADDMUL_1);
  596.   p->carry = CARRY_LIMB;
  597.   REFERENCE (refmpn_addmul_1c);
  598.   p = &param[TYPE_SUBMUL_1];
  599.   COPY (TYPE_ADDMUL_1);
  600.   REFERENCE (refmpn_submul_1);
  601.   p = &param[TYPE_SUBMUL_1C];
  602.   COPY (TYPE_ADDMUL_1C);
  603.   REFERENCE (refmpn_submul_1c);
  604.   p = &param[TYPE_ADDMUL_2];
  605.   p->retval = 1;
  606.   p->dst[0] = 1;
  607.   p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
  608.   p->src[0] = 1;
  609.   p->src[1] = 1;
  610.   p->msize = 2;
  611.   p->dst0_from_src1 = 1;
  612.   p->overlap = OVERLAP_NOT_SRC2;
  613.   REFERENCE (refmpn_addmul_2);
  614.   p = &param[TYPE_ADDMUL_3];
  615.   COPY (TYPE_ADDMUL_2);
  616.   p->msize = 3;
  617.   REFERENCE (refmpn_addmul_3);
  618.   p = &param[TYPE_ADDMUL_4];
  619.   COPY (TYPE_ADDMUL_2);
  620.   p->msize = 4;
  621.   REFERENCE (refmpn_addmul_4);
  622.   p = &param[TYPE_ADDMUL_5];
  623.   COPY (TYPE_ADDMUL_2);
  624.   p->msize = 5;
  625.   REFERENCE (refmpn_addmul_5);
  626.   p = &param[TYPE_ADDMUL_6];
  627.   COPY (TYPE_ADDMUL_2);
  628.   p->msize = 6;
  629.   REFERENCE (refmpn_addmul_6);
  630.   p = &param[TYPE_ADDMUL_7];
  631.   COPY (TYPE_ADDMUL_2);
  632.   p->msize = 7;
  633.   REFERENCE (refmpn_addmul_7);
  634.   p = &param[TYPE_ADDMUL_8];
  635.   COPY (TYPE_ADDMUL_2);
  636.   p->msize = 8;
  637.   REFERENCE (refmpn_addmul_8);
  638.   p = &param[TYPE_AND_N];
  639.   p->dst[0] = 1;
  640.   p->src[0] = 1;
  641.   p->src[1] = 1;
  642.   REFERENCE (refmpn_and_n);
  643.   p = &param[TYPE_ANDN_N];
  644.   COPY (TYPE_AND_N);
  645.   REFERENCE (refmpn_andn_n);
  646.   p = &param[TYPE_NAND_N];
  647.   COPY (TYPE_AND_N);
  648.   REFERENCE (refmpn_nand_n);
  649.   p = &param[TYPE_IOR_N];
  650.   COPY (TYPE_AND_N);
  651.   REFERENCE (refmpn_ior_n);
  652.   p = &param[TYPE_IORN_N];
  653.   COPY (TYPE_AND_N);
  654.   REFERENCE (refmpn_iorn_n);
  655.   p = &param[TYPE_NIOR_N];
  656.   COPY (TYPE_AND_N);
  657.   REFERENCE (refmpn_nior_n);
  658.   p = &param[TYPE_XOR_N];
  659.   COPY (TYPE_AND_N);
  660.   REFERENCE (refmpn_xor_n);
  661.   p = &param[TYPE_XNOR_N];
  662.   COPY (TYPE_AND_N);
  663.   REFERENCE (refmpn_xnor_n);
  664.   p = &param[TYPE_ADDSUB_N];
  665.   p->retval = 1;
  666.   p->dst[0] = 1;
  667.   p->dst[1] = 1;
  668.   p->src[0] = 1;
  669.   p->src[1] = 1;
  670.   REFERENCE (refmpn_add_n_sub_n);
  671.   p = &param[TYPE_ADDSUB_NC];
  672.   COPY (TYPE_ADDSUB_N);
  673.   p->carry = CARRY_4;
  674.   REFERENCE (refmpn_add_n_sub_nc);
  675.   p = &param[TYPE_COPY];
  676.   p->dst[0] = 1;
  677.   p->src[0] = 1;
  678.   p->overlap = OVERLAP_NONE;
  679.   p->size = SIZE_ALLOW_ZERO;
  680.   REFERENCE (refmpn_copy);
  681.   p = &param[TYPE_COPYI];
  682.   p->dst[0] = 1;
  683.   p->src[0] = 1;
  684.   p->overlap = OVERLAP_LOW_TO_HIGH;
  685.   p->size = SIZE_ALLOW_ZERO;
  686.   REFERENCE (refmpn_copyi);
  687.   p = &param[TYPE_COPYD];
  688.   p->dst[0] = 1;
  689.   p->src[0] = 1;
  690.   p->overlap = OVERLAP_HIGH_TO_LOW;
  691.   p->size = SIZE_ALLOW_ZERO;
  692.   REFERENCE (refmpn_copyd);
  693.   p = &param[TYPE_COM];
  694.   p->dst[0] = 1;
  695.   p->src[0] = 1;
  696.   REFERENCE (refmpn_com);
  697.   p = &param[TYPE_ADDLSH1_N];
  698.   COPY (TYPE_ADD_N);
  699.   REFERENCE (refmpn_addlsh1_n);
  700.   p = &param[TYPE_ADDLSH2_N];
  701.   COPY (TYPE_ADD_N);
  702.   REFERENCE (refmpn_addlsh2_n);
  703.   p = &param[TYPE_ADDLSH_N];
  704.   COPY (TYPE_ADD_N);
  705.   p->shift = 1;
  706.   REFERENCE (refmpn_addlsh_n);
  707.   p = &param[TYPE_SUBLSH1_N];
  708.   COPY (TYPE_ADD_N);
  709.   REFERENCE (refmpn_sublsh1_n);
  710.   p = &param[TYPE_SUBLSH_N];
  711.   COPY (TYPE_ADDLSH_N);
  712.   REFERENCE (refmpn_sublsh_n);
  713.   p = &param[TYPE_RSBLSH1_N];
  714.   COPY (TYPE_ADD_N);
  715.   REFERENCE (refmpn_rsblsh1_n);
  716.   p = &param[TYPE_RSBLSH2_N];
  717.   COPY (TYPE_ADD_N);
  718.   REFERENCE (refmpn_rsblsh2_n);
  719.   p = &param[TYPE_RSBLSH_N];
  720.   COPY (TYPE_ADDLSH_N);
  721.   REFERENCE (refmpn_rsblsh_n);
  722.   p = &param[TYPE_RSH1ADD_N];
  723.   COPY (TYPE_ADD_N);
  724.   REFERENCE (refmpn_rsh1add_n);
  725.   p = &param[TYPE_RSH1SUB_N];
  726.   COPY (TYPE_ADD_N);
  727.   REFERENCE (refmpn_rsh1sub_n);
  728.   p = &param[TYPE_MOD_1];
  729.   p->retval = 1;
  730.   p->src[0] = 1;
  731.   p->size = SIZE_ALLOW_ZERO;
  732.   p->divisor = DIVISOR_LIMB;
  733.   REFERENCE (refmpn_mod_1);
  734.   p = &param[TYPE_MOD_1C];
  735.   COPY (TYPE_MOD_1);
  736.   p->carry = CARRY_DIVISOR;
  737.   REFERENCE (refmpn_mod_1c);
  738.   p = &param[TYPE_DIVMOD_1];
  739.   COPY (TYPE_MOD_1);
  740.   p->dst[0] = 1;
  741.   REFERENCE (refmpn_divmod_1);
  742.   p = &param[TYPE_DIVMOD_1C];
  743.   COPY (TYPE_DIVMOD_1);
  744.   p->carry = CARRY_DIVISOR;
  745.   REFERENCE (refmpn_divmod_1c);
  746.   p = &param[TYPE_DIVREM_1];
  747.   COPY (TYPE_DIVMOD_1);
  748.   p->size2 = SIZE_FRACTION;
  749.   p->dst_size[0] = SIZE_SUM;
  750.   REFERENCE (refmpn_divrem_1);
  751.   p = &param[TYPE_DIVREM_1C];
  752.   COPY (TYPE_DIVREM_1);
  753.   p->carry = CARRY_DIVISOR;
  754.   REFERENCE (refmpn_divrem_1c);
  755.   p = &param[TYPE_PREINV_DIVREM_1];
  756.   COPY (TYPE_DIVREM_1);
  757.   p->size = SIZE_YES; /* ie. no size==0 */
  758.   REFERENCE (refmpn_preinv_divrem_1);
  759.   p = &param[TYPE_PREINV_MOD_1];
  760.   p->retval = 1;
  761.   p->src[0] = 1;
  762.   p->divisor = DIVISOR_NORM;
  763.   REFERENCE (refmpn_preinv_mod_1);
  764.   p = &param[TYPE_MOD_34LSUB1];
  765.   p->retval = 1;
  766.   p->src[0] = 1;
  767.   VALIDATE (validate_mod_34lsub1);
  768.   p = &param[TYPE_UDIV_QRNND];
  769.   p->retval = 1;
  770.   p->src[0] = 1;
  771.   p->dst[0] = 1;
  772.   p->dst_size[0] = SIZE_1;
  773.   p->divisor = UDIV_NEEDS_NORMALIZATION ? DIVISOR_NORM : DIVISOR_LIMB;
  774.   p->data = DATA_UDIV_QRNND;
  775.   p->overlap = OVERLAP_NONE;
  776.   REFERENCE (refmpn_udiv_qrnnd);
  777.   p = &param[TYPE_UDIV_QRNND_R];
  778.   COPY (TYPE_UDIV_QRNND);
  779.   REFERENCE (refmpn_udiv_qrnnd_r);
  780.   p = &param[TYPE_DIVEXACT_1];
  781.   p->dst[0] = 1;
  782.   p->src[0] = 1;
  783.   p->divisor = DIVISOR_LIMB;
  784.   p->data = DATA_MULTIPLE_DIVISOR;
  785.   VALIDATE (validate_divexact_1);
  786.   REFERENCE (refmpn_divmod_1);
  787.   p = &param[TYPE_DIVEXACT_BY3];
  788.   p->retval = 1;
  789.   p->dst[0] = 1;
  790.   p->src[0] = 1;
  791.   REFERENCE (refmpn_divexact_by3);
  792.   p = &param[TYPE_DIVEXACT_BY3C];
  793.   COPY (TYPE_DIVEXACT_BY3);
  794.   p->carry = CARRY_3;
  795.   REFERENCE (refmpn_divexact_by3c);
  796.   p = &param[TYPE_MODEXACT_1_ODD];
  797.   p->retval = 1;
  798.   p->src[0] = 1;
  799.   p->divisor = DIVISOR_ODD;
  800.   VALIDATE (validate_modexact_1_odd);
  801.   p = &param[TYPE_MODEXACT_1C_ODD];
  802.   COPY (TYPE_MODEXACT_1_ODD);
  803.   p->carry = CARRY_LIMB;
  804.   VALIDATE (validate_modexact_1c_odd);
  805.   p = &param[TYPE_GCD_1];
  806.   p->retval = 1;
  807.   p->src[0] = 1;
  808.   p->data = DATA_NON_ZERO;
  809.   p->divisor = DIVISOR_LIMB;
  810.   REFERENCE (refmpn_gcd_1);
  811.   p = &param[TYPE_GCD];
  812.   p->retval = 1;
  813.   p->dst[0] = 1;
  814.   p->src[0] = 1;
  815.   p->src[1] = 1;
  816.   p->size2 = 1;
  817.   p->dst_size[0] = SIZE_RETVAL;
  818.   p->overlap = OVERLAP_NOT_SRCS;
  819.   p->data = DATA_GCD;
  820.   REFERENCE (refmpn_gcd);
  821.   p = &param[TYPE_MPZ_JACOBI];
  822.   p->retval = 1;
  823.   p->src[0] = 1;
  824.   p->size = SIZE_ALLOW_ZERO;
  825.   p->src[1] = 1;
  826.   p->data = DATA_SRC1_ODD;
  827.   p->size2 = 1;
  828.   p->carry = CARRY_4;
  829.   p->carry_sign = 1;
  830.   REFERENCE (refmpz_jacobi);
  831.   p = &param[TYPE_MPZ_KRONECKER];
  832.   COPY (TYPE_MPZ_JACOBI);
  833.   p->data = 0; /* clear inherited DATA_SRC1_ODD */
  834.   REFERENCE (refmpz_kronecker);
  835.   p = &param[TYPE_MPZ_KRONECKER_UI];
  836.   p->retval = 1;
  837.   p->src[0] = 1;
  838.   p->size = SIZE_ALLOW_ZERO;
  839.   p->multiplier = 1;
  840.   p->carry = CARRY_BIT;
  841.   REFERENCE (refmpz_kronecker_ui);
  842.   p = &param[TYPE_MPZ_KRONECKER_SI];
  843.   COPY (TYPE_MPZ_KRONECKER_UI);
  844.   REFERENCE (refmpz_kronecker_si);
  845.   p = &param[TYPE_MPZ_UI_KRONECKER];
  846.   COPY (TYPE_MPZ_KRONECKER_UI);
  847.   REFERENCE (refmpz_ui_kronecker);
  848.   p = &param[TYPE_MPZ_SI_KRONECKER];
  849.   COPY (TYPE_MPZ_KRONECKER_UI);
  850.   REFERENCE (refmpz_si_kronecker);
  851.   p = &param[TYPE_SQR];
  852.   p->dst[0] = 1;
  853.   p->src[0] = 1;
  854.   p->dst_size[0] = SIZE_SUM;
  855.   p->overlap = OVERLAP_NONE;
  856.   REFERENCE (refmpn_sqr);
  857.   p = &param[TYPE_MUL_N];
  858.   COPY (TYPE_SQR);
  859.   p->src[1] = 1;
  860.   REFERENCE (refmpn_mul_n);
  861.   p = &param[TYPE_MULLO_N];
  862.   COPY (TYPE_MUL_N);
  863.   p->dst_size[0] = 0;
  864.   REFERENCE (refmpn_mullo_n);
  865.   p = &param[TYPE_MUL_MN];
  866.   COPY (TYPE_MUL_N);
  867.   p->size2 = 1;
  868.   REFERENCE (refmpn_mul_basecase);
  869.   p = &param[TYPE_UMUL_PPMM];
  870.   p->retval = 1;
  871.   p->src[0] = 1;
  872.   p->dst[0] = 1;
  873.   p->dst_size[0] = SIZE_1;
  874.   p->overlap = OVERLAP_NONE;
  875.   REFERENCE (refmpn_umul_ppmm);
  876.   p = &param[TYPE_UMUL_PPMM_R];
  877.   COPY (TYPE_UMUL_PPMM);
  878.   REFERENCE (refmpn_umul_ppmm_r);
  879.   p = &param[TYPE_RSHIFT];
  880.   p->retval = 1;
  881.   p->dst[0] = 1;
  882.   p->src[0] = 1;
  883.   p->shift = 1;
  884.   p->overlap = OVERLAP_LOW_TO_HIGH;
  885.   REFERENCE (refmpn_rshift);
  886.   p = &param[TYPE_LSHIFT];
  887.   COPY (TYPE_RSHIFT);
  888.   p->overlap = OVERLAP_HIGH_TO_LOW;
  889.   REFERENCE (refmpn_lshift);
  890.   p = &param[TYPE_LSHIFTC];
  891.   COPY (TYPE_RSHIFT);
  892.   p->overlap = OVERLAP_HIGH_TO_LOW;
  893.   REFERENCE (refmpn_lshiftc);
  894.   p = &param[TYPE_POPCOUNT];
  895.   p->retval = 1;
  896.   p->src[0] = 1;
  897.   REFERENCE (refmpn_popcount);
  898.   p = &param[TYPE_HAMDIST];
  899.   COPY (TYPE_POPCOUNT);
  900.   p->src[1] = 1;
  901.   REFERENCE (refmpn_hamdist);
  902.   p = &param[TYPE_SBPI1_DIV_QR];
  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.   p->data = DATA_SRC1_HIGHBIT;
  909.   p->size2 = 1;
  910.   p->dst_size[0] = SIZE_DIFF;
  911.   p->overlap = OVERLAP_NONE;
  912.   REFERENCE (refmpn_sb_div_qr);
  913.   p = &param[TYPE_TDIV_QR];
  914.   p->dst[0] = 1;
  915.   p->dst[1] = 1;
  916.   p->src[0] = 1;
  917.   p->src[1] = 1;
  918.   p->size2 = 1;
  919.   p->dst_size[0] = SIZE_DIFF_PLUS_1;
  920.   p->dst_size[1] = SIZE_SIZE2;
  921.   p->overlap = OVERLAP_NONE;
  922.   REFERENCE (refmpn_tdiv_qr);
  923.   p = &param[TYPE_SQRTREM];
  924.   p->retval = 1;
  925.   p->dst[0] = 1;
  926.   p->dst[1] = 1;
  927.   p->src[0] = 1;
  928.   p->dst_size[0] = SIZE_CEIL_HALF;
  929.   p->dst_size[1] = SIZE_RETVAL;
  930.   p->overlap = OVERLAP_NONE;
  931.   VALIDATE (validate_sqrtrem);
  932.   REFERENCE (refmpn_sqrtrem);
  933.   p = &param[TYPE_ZERO];
  934.   p->dst[0] = 1;
  935.   p->size = SIZE_ALLOW_ZERO;
  936.   REFERENCE (refmpn_zero);
  937.   p = &param[TYPE_GET_STR];
  938.   p->retval = 1;
  939.   p->src[0] = 1;
  940.   p->size = SIZE_ALLOW_ZERO;
  941.   p->dst[0] = 1;
  942.   p->dst[1] = 1;
  943.   p->dst_size[0] = SIZE_GET_STR;
  944.   p->dst_bytes[0] = 1;
  945.   p->overlap = OVERLAP_NONE;
  946.   REFERENCE (refmpn_get_str);
  947.   p = &param[TYPE_BINVERT];
  948.   p->dst[0] = 1;
  949.   p->src[0] = 1;
  950.   p->data = DATA_SRC0_ODD;
  951.   p->overlap = OVERLAP_NONE;
  952.   REFERENCE (refmpn_binvert);
  953.   p = &param[TYPE_INVERT];
  954.   p->dst[0] = 1;
  955.   p->src[0] = 1;
  956.   p->data = DATA_SRC0_HIGHBIT;
  957.   p->overlap = OVERLAP_NONE;
  958.   REFERENCE (refmpn_invert);
  959. #ifdef EXTRA_PARAM_INIT
  960.   EXTRA_PARAM_INIT
  961. #endif
  962. }
  963. /* The following are macros if there's no native versions, so wrap them in
  964.    functions that can be in try_array[]. */
  965. void
  966. MPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  967. { MPN_COPY (rp, sp, size); }
  968. void
  969. MPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  970. { MPN_COPY_INCR (rp, sp, size); }
  971. void
  972. MPN_COPY_DECR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  973. { MPN_COPY_DECR (rp, sp, size); }
  974. void
  975. __GMPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  976. { __GMPN_COPY (rp, sp, size); }
  977. #ifdef __GMPN_COPY_INCR
  978. void
  979. __GMPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  980. { __GMPN_COPY_INCR (rp, sp, size); }
  981. #endif
  982. void
  983. mpn_com_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  984. { mpn_com (rp, sp, size); }
  985. void
  986. mpn_and_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  987. { mpn_and_n (rp, s1, s2, size); }
  988. void
  989. mpn_andn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  990. { mpn_andn_n (rp, s1, s2, size); }
  991. void
  992. mpn_nand_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  993. { mpn_nand_n (rp, s1, s2, size); }
  994. void
  995. mpn_ior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  996. { mpn_ior_n (rp, s1, s2, size); }
  997. void
  998. mpn_iorn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  999. { mpn_iorn_n (rp, s1, s2, size); }
  1000. void
  1001. mpn_nior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  1002. { mpn_nior_n (rp, s1, s2, size); }
  1003. void
  1004. mpn_xor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  1005. { mpn_xor_n (rp, s1, s2, size); }
  1006. void
  1007. mpn_xnor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
  1008. { mpn_xnor_n (rp, s1, s2, size); }
  1009. mp_limb_t
  1010. udiv_qrnnd_fun (mp_limb_t *remptr, mp_limb_t n1, mp_limb_t n0, mp_limb_t d)
  1011. {
  1012.   mp_limb_t  q;
  1013.   udiv_qrnnd (q, *remptr, n1, n0, d);
  1014.   return q;
  1015. }
  1016. mp_limb_t
  1017. mpn_divexact_by3_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  1018. {
  1019.   return mpn_divexact_by3 (rp, sp, size);
  1020. }
  1021. mp_limb_t
  1022. mpn_modexact_1_odd_fun (mp_srcptr ptr, mp_size_t size, mp_limb_t divisor)
  1023. {
  1024.   return mpn_modexact_1_odd (ptr, size, divisor);
  1025. }
  1026. void
  1027. mpn_toom22_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
  1028. {
  1029.   mp_ptr  tspace;
  1030.   TMP_DECL;
  1031.   TMP_MARK;
  1032.   tspace = TMP_ALLOC_LIMBS (mpn_toom22_mul_itch (size, size));
  1033.   mpn_toom22_mul (dst, src1, size, src2, size, tspace);
  1034.   TMP_FREE;
  1035. }
  1036. void
  1037. mpn_toom2_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
  1038. {
  1039.   mp_ptr tspace;
  1040.   TMP_DECL;
  1041.   TMP_MARK;
  1042.   tspace = TMP_ALLOC_LIMBS (mpn_toom2_sqr_itch (size));
  1043.   mpn_toom2_sqr (dst, src, size, tspace);
  1044.   TMP_FREE;
  1045. }
  1046. void
  1047. mpn_toom33_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
  1048. {
  1049.   mp_ptr  tspace;
  1050.   TMP_DECL;
  1051.   TMP_MARK;
  1052.   tspace = TMP_ALLOC_LIMBS (mpn_toom33_mul_itch (size, size));
  1053.   mpn_toom33_mul (dst, src1, size, src2, size, tspace);
  1054.   TMP_FREE;
  1055. }
  1056. void
  1057. mpn_toom3_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
  1058. {
  1059.   mp_ptr tspace;
  1060.   TMP_DECL;
  1061.   TMP_MARK;
  1062.   tspace = TMP_ALLOC_LIMBS (mpn_toom3_sqr_itch (size));
  1063.   mpn_toom3_sqr (dst, src, size, tspace);
  1064.   TMP_FREE;
  1065. }
  1066. void
  1067. mpn_toom44_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
  1068. {
  1069.   mp_ptr  tspace;
  1070.   TMP_DECL;
  1071.   TMP_MARK;
  1072.   tspace = TMP_ALLOC_LIMBS (mpn_toom44_mul_itch (size, size));
  1073.   mpn_toom44_mul (dst, src1, size, src2, size, tspace);
  1074.   TMP_FREE;
  1075. }
  1076. void
  1077. mpn_toom4_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
  1078. {
  1079.   mp_ptr tspace;
  1080.   TMP_DECL;
  1081.   TMP_MARK;
  1082.   tspace = TMP_ALLOC_LIMBS (mpn_toom4_sqr_itch (size));
  1083.   mpn_toom4_sqr (dst, src, size, tspace);
  1084.   TMP_FREE;
  1085. }
  1086. mp_limb_t
  1087. umul_ppmm_fun (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2)
  1088. {
  1089.   mp_limb_t  high;
  1090.   umul_ppmm (high, *lowptr, m1, m2);
  1091.   return high;
  1092. }
  1093. void
  1094. MPN_ZERO_fun (mp_ptr ptr, mp_size_t size)
  1095. { MPN_ZERO (ptr, size); }
  1096. struct choice_t {
  1097.   const char  *name;
  1098.   tryfun_t    function;
  1099.   int         type;
  1100.   mp_size_t   minsize;
  1101. };
  1102. #if HAVE_STRINGIZE
  1103. #define TRY(fun)        #fun, (tryfun_t) fun
  1104. #define TRY_FUNFUN(fun) #fun, (tryfun_t) fun##_fun
  1105. #else
  1106. #define TRY(fun)        "fun", (tryfun_t) fun
  1107. #define TRY_FUNFUN(fun) "fun", (tryfun_t) fun/**/_fun
  1108. #endif
  1109. const struct choice_t choice_array[] = {
  1110.   { TRY(mpn_add),       TYPE_ADD    },
  1111.   { TRY(mpn_sub),       TYPE_SUB    },
  1112.   { TRY(mpn_add_n),     TYPE_ADD_N  },
  1113.   { TRY(mpn_sub_n),     TYPE_SUB_N  },
  1114. #if HAVE_NATIVE_mpn_add_nc
  1115.   { TRY(mpn_add_nc),    TYPE_ADD_NC },
  1116. #endif
  1117. #if HAVE_NATIVE_mpn_sub_nc
  1118.   { TRY(mpn_sub_nc),    TYPE_SUB_NC },
  1119. #endif
  1120. #if HAVE_NATIVE_mpn_add_n_sub_n
  1121.   { TRY(mpn_add_n_sub_n),  TYPE_ADDSUB_N  },
  1122. #endif
  1123. #if HAVE_NATIVE_mpn_add_n_sub_nc
  1124.   { TRY(mpn_add_n_sub_nc), TYPE_ADDSUB_NC },
  1125. #endif
  1126.   { TRY(mpn_addmul_1),  TYPE_ADDMUL_1  },
  1127.   { TRY(mpn_submul_1),  TYPE_SUBMUL_1  },
  1128. #if HAVE_NATIVE_mpn_addmul_1c
  1129.   { TRY(mpn_addmul_1c), TYPE_ADDMUL_1C },
  1130. #endif
  1131. #if HAVE_NATIVE_mpn_submul_1c
  1132.   { TRY(mpn_submul_1c), TYPE_SUBMUL_1C },
  1133. #endif
  1134. #if HAVE_NATIVE_mpn_addmul_2
  1135.   { TRY(mpn_addmul_2), TYPE_ADDMUL_2, 2 },
  1136. #endif
  1137. #if HAVE_NATIVE_mpn_addmul_3
  1138.   { TRY(mpn_addmul_3), TYPE_ADDMUL_3, 3 },
  1139. #endif
  1140. #if HAVE_NATIVE_mpn_addmul_4
  1141.   { TRY(mpn_addmul_4), TYPE_ADDMUL_4, 4 },
  1142. #endif
  1143. #if HAVE_NATIVE_mpn_addmul_5
  1144.   { TRY(mpn_addmul_5), TYPE_ADDMUL_5, 5 },
  1145. #endif
  1146. #if HAVE_NATIVE_mpn_addmul_6
  1147.   { TRY(mpn_addmul_6), TYPE_ADDMUL_6, 6 },
  1148. #endif
  1149. #if HAVE_NATIVE_mpn_addmul_7
  1150.   { TRY(mpn_addmul_7), TYPE_ADDMUL_7, 7 },
  1151. #endif
  1152. #if HAVE_NATIVE_mpn_addmul_8
  1153.   { TRY(mpn_addmul_8), TYPE_ADDMUL_8, 8 },
  1154. #endif
  1155.   { TRY_FUNFUN(mpn_com),  TYPE_COM },
  1156.   { TRY_FUNFUN(MPN_COPY),      TYPE_COPY },
  1157.   { TRY_FUNFUN(MPN_COPY_INCR), TYPE_COPYI },
  1158.   { TRY_FUNFUN(MPN_COPY_DECR), TYPE_COPYD },
  1159.   { TRY_FUNFUN(__GMPN_COPY),      TYPE_COPY },
  1160. #ifdef __GMPN_COPY_INCR
  1161.   { TRY_FUNFUN(__GMPN_COPY_INCR), TYPE_COPYI },
  1162. #endif
  1163. #if HAVE_NATIVE_mpn_copyi
  1164.   { TRY(mpn_copyi), TYPE_COPYI },
  1165. #endif
  1166. #if HAVE_NATIVE_mpn_copyd
  1167.   { TRY(mpn_copyd), TYPE_COPYD },
  1168. #endif
  1169. #if HAVE_NATIVE_mpn_addlsh1_n
  1170.   { TRY(mpn_addlsh1_n), TYPE_ADDLSH1_N },
  1171. #endif
  1172. #if HAVE_NATIVE_mpn_addlsh2_n
  1173.   { TRY(mpn_addlsh2_n), TYPE_ADDLSH2_N },
  1174. #endif
  1175. #if HAVE_NATIVE_mpn_addlsh_n
  1176.   { TRY(mpn_addlsh_n), TYPE_ADDLSH_N },
  1177. #endif
  1178. #if HAVE_NATIVE_mpn_sublsh1_n
  1179.   { TRY(mpn_sublsh1_n), TYPE_SUBLSH1_N },
  1180. #endif
  1181. #if HAVE_NATIVE_mpn_sublsh_n
  1182.   { TRY(mpn_sublsh_n), TYPE_SUBLSH_N },
  1183. #endif
  1184. #if HAVE_NATIVE_mpn_rsblsh1_n
  1185.   { TRY(mpn_rsblsh1_n), TYPE_RSBLSH1_N },
  1186. #endif
  1187. #if HAVE_NATIVE_mpn_rsblsh2_n
  1188.   { TRY(mpn_rsblsh2_n), TYPE_RSBLSH2_N },
  1189. #endif
  1190. #if HAVE_NATIVE_mpn_rsblsh_n
  1191.   { TRY(mpn_rsblsh_n), TYPE_RSBLSH_N },
  1192. #endif
  1193. #if HAVE_NATIVE_mpn_rsh1add_n
  1194.   { TRY(mpn_rsh1add_n), TYPE_RSH1ADD_N },
  1195. #endif
  1196. #if HAVE_NATIVE_mpn_rsh1sub_n
  1197.   { TRY(mpn_rsh1sub_n), TYPE_RSH1SUB_N },
  1198. #endif
  1199.   { TRY_FUNFUN(mpn_and_n),  TYPE_AND_N  },
  1200.   { TRY_FUNFUN(mpn_andn_n), TYPE_ANDN_N },
  1201.   { TRY_FUNFUN(mpn_nand_n), TYPE_NAND_N },
  1202.   { TRY_FUNFUN(mpn_ior_n),  TYPE_IOR_N  },
  1203.   { TRY_FUNFUN(mpn_iorn_n), TYPE_IORN_N },
  1204.   { TRY_FUNFUN(mpn_nior_n), TYPE_NIOR_N },
  1205.   { TRY_FUNFUN(mpn_xor_n),  TYPE_XOR_N  },
  1206.   { TRY_FUNFUN(mpn_xnor_n), TYPE_XNOR_N },
  1207.   { TRY(mpn_divrem_1),     TYPE_DIVREM_1 },
  1208. #if USE_PREINV_DIVREM_1
  1209.   { TRY(mpn_preinv_divrem_1), TYPE_PREINV_DIVREM_1 },
  1210. #endif
  1211.   { TRY(mpn_mod_1),        TYPE_MOD_1 },
  1212. #if USE_PREINV_MOD_1
  1213.   { TRY(mpn_preinv_mod_1), TYPE_PREINV_MOD_1 },
  1214. #endif
  1215. #if HAVE_NATIVE_mpn_divrem_1c
  1216.   { TRY(mpn_divrem_1c),    TYPE_DIVREM_1C },
  1217. #endif
  1218. #if HAVE_NATIVE_mpn_mod_1c
  1219.   { TRY(mpn_mod_1c),       TYPE_MOD_1C },
  1220. #endif
  1221. #if GMP_NUMB_BITS % 4 == 0
  1222.   { TRY(mpn_mod_34lsub1),  TYPE_MOD_34LSUB1 },
  1223. #endif
  1224.   { TRY_FUNFUN(udiv_qrnnd), TYPE_UDIV_QRNND, 2 },
  1225. #if HAVE_NATIVE_mpn_udiv_qrnnd
  1226.   { TRY(mpn_udiv_qrnnd),    TYPE_UDIV_QRNND, 2 },
  1227. #endif
  1228. #if HAVE_NATIVE_mpn_udiv_qrnnd_r
  1229.   { TRY(mpn_udiv_qrnnd_r),  TYPE_UDIV_QRNND_R, 2 },
  1230. #endif
  1231.   { TRY(mpn_divexact_1),          TYPE_DIVEXACT_1 },
  1232.   { TRY_FUNFUN(mpn_divexact_by3), TYPE_DIVEXACT_BY3 },
  1233.   { TRY(mpn_divexact_by3c),       TYPE_DIVEXACT_BY3C },
  1234.   { TRY_FUNFUN(mpn_modexact_1_odd), TYPE_MODEXACT_1_ODD },
  1235.   { TRY(mpn_modexact_1c_odd),       TYPE_MODEXACT_1C_ODD },
  1236.   { TRY(mpn_sbpi1_div_qr), TYPE_SBPI1_DIV_QR, 3},
  1237.   { TRY(mpn_tdiv_qr),      TYPE_TDIV_QR },
  1238.   { TRY(mpn_mul_1),      TYPE_MUL_1 },
  1239. #if HAVE_NATIVE_mpn_mul_1c
  1240.   { TRY(mpn_mul_1c),     TYPE_MUL_1C },
  1241. #endif
  1242. #if HAVE_NATIVE_mpn_mul_2
  1243.   { TRY(mpn_mul_2),      TYPE_MUL_2, 2 },
  1244. #endif
  1245. #if HAVE_NATIVE_mpn_mul_3
  1246.   { TRY(mpn_mul_3),      TYPE_MUL_3, 3 },
  1247. #endif
  1248. #if HAVE_NATIVE_mpn_mul_4
  1249.   { TRY(mpn_mul_4),      TYPE_MUL_4, 4 },
  1250. #endif
  1251.   { TRY(mpn_rshift),     TYPE_RSHIFT },
  1252.   { TRY(mpn_lshift),     TYPE_LSHIFT },
  1253.   { TRY(mpn_lshiftc),    TYPE_LSHIFTC },
  1254.   { TRY(mpn_mul_basecase), TYPE_MUL_MN },
  1255.   { TRY(mpn_mullo_basecase), TYPE_MULLO_N },
  1256. #if SQR_TOOM2_THRESHOLD > 0
  1257.   { TRY(mpn_sqr_basecase), TYPE_SQR },
  1258. #endif
  1259.   { TRY(mpn_mul),    TYPE_MUL_MN },
  1260.   { TRY(mpn_mul_n),  TYPE_MUL_N },
  1261.   { TRY(mpn_sqr),    TYPE_SQR },
  1262.   { TRY_FUNFUN(umul_ppmm), TYPE_UMUL_PPMM, 2 },
  1263. #if HAVE_NATIVE_mpn_umul_ppmm
  1264.   { TRY(mpn_umul_ppmm),    TYPE_UMUL_PPMM, 2 },
  1265. #endif
  1266. #if HAVE_NATIVE_mpn_umul_ppmm_r
  1267.   { TRY(mpn_umul_ppmm_r),  TYPE_UMUL_PPMM_R, 2 },
  1268. #endif
  1269.   { TRY_FUNFUN(mpn_toom22_mul),  TYPE_MUL_N,  MPN_TOOM22_MUL_MINSIZE },
  1270.   { TRY_FUNFUN(mpn_toom2_sqr),   TYPE_SQR,    MPN_TOOM2_SQR_MINSIZE },
  1271.   { TRY_FUNFUN(mpn_toom33_mul),  TYPE_MUL_N,  MPN_TOOM33_MUL_MINSIZE },
  1272.   { TRY_FUNFUN(mpn_toom3_sqr),   TYPE_SQR,    MPN_TOOM3_SQR_MINSIZE },
  1273.   { TRY_FUNFUN(mpn_toom44_mul),  TYPE_MUL_N,  MPN_TOOM44_MUL_MINSIZE },
  1274.   { TRY_FUNFUN(mpn_toom4_sqr),   TYPE_SQR,    MPN_TOOM4_SQR_MINSIZE },
  1275.   { TRY(mpn_gcd_1),        TYPE_GCD_1            },
  1276.   { TRY(mpn_gcd),          TYPE_GCD              },
  1277.   { TRY(mpz_jacobi),       TYPE_MPZ_JACOBI       },
  1278.   { TRY(mpz_kronecker_ui), TYPE_MPZ_KRONECKER_UI },
  1279.   { TRY(mpz_kronecker_si), TYPE_MPZ_KRONECKER_SI },
  1280.   { TRY(mpz_ui_kronecker), TYPE_MPZ_UI_KRONECKER },
  1281.   { TRY(mpz_si_kronecker), TYPE_MPZ_SI_KRONECKER },
  1282.   { TRY(mpn_popcount),   TYPE_POPCOUNT },
  1283.   { TRY(mpn_hamdist),    TYPE_HAMDIST },
  1284.   { TRY(mpn_sqrtrem),    TYPE_SQRTREM },
  1285.   { TRY_FUNFUN(MPN_ZERO), TYPE_ZERO },
  1286.   { TRY(mpn_get_str),    TYPE_GET_STR },
  1287.   { TRY(mpn_binvert),    TYPE_BINVERT },
  1288.   { TRY(mpn_invert),     TYPE_INVERT  },
  1289. #ifdef EXTRA_ROUTINES
  1290.   EXTRA_ROUTINES
  1291. #endif
  1292. };
  1293. const struct choice_t *choice = NULL;
  1294. void
  1295. mprotect_maybe (void *addr, size_t len, int prot)
  1296. {
  1297.   if (!option_redzones)
  1298.     return;
  1299. #if HAVE_MPROTECT
  1300.   if (mprotect (addr, len, prot) != 0)
  1301.     {
  1302.       fprintf (stderr, "Cannot mprotect %p 0x%X 0x%X: %sn",
  1303.        addr, (unsigned) len, prot, strerror (errno));
  1304.       exit (1);
  1305.     }
  1306. #else
  1307.   {
  1308.     static int  warned = 0;
  1309.     if (!warned)
  1310.       {
  1311. fprintf (stderr,
  1312.  "mprotect not available, bounds testing not performedn");
  1313. warned = 1;
  1314.       }
  1315.   }
  1316. #endif
  1317. }
  1318. /* round "a" up to a multiple of "m" */
  1319. size_t
  1320. round_up_multiple (size_t a, size_t m)
  1321. {
  1322.   unsigned long  r;
  1323.   r = a % m;
  1324.   if (r == 0)
  1325.     return a;
  1326.   else
  1327.     return a + (m - r);
  1328. }
  1329. /* On some systems it seems that only an mmap'ed region can be mprotect'ed,
  1330.    for instance HP-UX 10.
  1331.    mmap will almost certainly return a pointer already aligned to a page
  1332.    boundary, but it's easy enough to share the alignment handling with the
  1333.    malloc case. */
  1334. void
  1335. malloc_region (struct region_t *r, mp_size_t n)
  1336. {
  1337.   mp_ptr  p;
  1338.   size_t  nbytes;
  1339.   ASSERT ((pagesize % BYTES_PER_MP_LIMB) == 0);
  1340.   n = round_up_multiple (n, PAGESIZE_LIMBS);
  1341.   r->size = n;
  1342.   nbytes = n*BYTES_PER_MP_LIMB + 2*REDZONE_BYTES + pagesize;
  1343. #if defined (MAP_ANONYMOUS) && ! defined (MAP_ANON)
  1344. #define MAP_ANON  MAP_ANONYMOUS
  1345. #endif
  1346. #if HAVE_MMAP && defined (MAP_ANON)
  1347.   /* note must pass fd=-1 for MAP_ANON on BSD */
  1348.   p = mmap (NULL, nbytes, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
  1349.   if (p == (void *) -1)
  1350.     {
  1351.       fprintf (stderr, "Cannot mmap %#x anon bytes: %sn",
  1352.        (unsigned) nbytes, strerror (errno));
  1353.       exit (1);
  1354.     }
  1355. #else
  1356.   p = (mp_ptr) malloc (nbytes);
  1357.   ASSERT_ALWAYS (p != NULL);
  1358. #endif
  1359.   p = align_pointer (p, pagesize);
  1360.   mprotect_maybe (p, REDZONE_BYTES, PROT_NONE);
  1361.   p += REDZONE_LIMBS;
  1362.   r->ptr = p;
  1363.   mprotect_maybe (p + n, REDZONE_BYTES, PROT_NONE);
  1364. }
  1365. void
  1366. mprotect_region (const struct region_t *r, int prot)
  1367. {
  1368.   mprotect_maybe (r->ptr, r->size, prot);
  1369. }
  1370. /* First four entries must be 0,1,2,3 for the benefit of CARRY_BIT, CARRY_3,
  1371.    and CARRY_4 */
  1372. mp_limb_t  carry_array[] = {
  1373.   0, 1, 2, 3,
  1374.   4,
  1375.   CNST_LIMB(1) << 8,
  1376.   CNST_LIMB(1) << 16,
  1377.   GMP_NUMB_MAX
  1378. };
  1379. int        carry_index;
  1380. #define CARRY_COUNT                                             
  1381.   ((tr->carry == CARRY_BIT) ? 2                                 
  1382.    : tr->carry == CARRY_3   ? 3                                 
  1383.    : tr->carry == CARRY_4   ? 4                                 
  1384.    : (tr->carry == CARRY_LIMB || tr->carry == CARRY_DIVISOR)    
  1385.      ? numberof(carry_array) + CARRY_RANDOMS                    
  1386.    : 1)
  1387. #define MPN_RANDOM_ALT(index,dst,size) 
  1388.   (((index) & 1) ? refmpn_random (dst, size) : refmpn_random2 (dst, size))
  1389. /* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
  1390.    the same type */
  1391. #define CARRY_ITERATION                                                 
  1392.   for (carry_index = 0;                                                 
  1393.        (carry_index < numberof (carry_array)                            
  1394. ? (carry = carry_array[carry_index])                            
  1395. : (MPN_RANDOM_ALT (carry_index, &carry, 1), (mp_limb_t) 0)),    
  1396.  (tr->carry == CARRY_DIVISOR ? carry %= divisor : 0),           
  1397.  carry_index < CARRY_COUNT;                                     
  1398.        carry_index++)
  1399. mp_limb_t  multiplier_array[] = {
  1400.   0, 1, 2, 3,
  1401.   CNST_LIMB(1) << 8,
  1402.   CNST_LIMB(1) << 16,
  1403.   GMP_NUMB_MAX - 2,
  1404.   GMP_NUMB_MAX - 1,
  1405.   GMP_NUMB_MAX
  1406. };
  1407. int        multiplier_index;
  1408. mp_limb_t  divisor_array[] = {
  1409.   1, 2, 3,
  1410.   CNST_LIMB(1) << 8,
  1411.   CNST_LIMB(1) << 16,
  1412.   CNST_LIMB(1) << (GMP_NUMB_BITS/2 - 1),
  1413.   GMP_NUMB_MAX >> (GMP_NUMB_BITS/2),
  1414.   GMP_NUMB_HIGHBIT,
  1415.   GMP_NUMB_HIGHBIT + 1,
  1416.   GMP_NUMB_MAX - 2,
  1417.   GMP_NUMB_MAX - 1,
  1418.   GMP_NUMB_MAX
  1419. };
  1420. int        divisor_index;
  1421. /* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
  1422.    the same type */
  1423. #define ARRAY_ITERATION(var, index, limit, array, randoms, cond)        
  1424.   for (index = 0;                                                       
  1425.        (index < numberof (array)                                        
  1426. ? (var = array[index])                                          
  1427. : (MPN_RANDOM_ALT (index, &var, 1), (mp_limb_t) 0)),            
  1428.        index < limit;                                                   
  1429.        index++)
  1430. #define MULTIPLIER_COUNT                                
  1431.   (tr->multiplier                                       
  1432.     ? numberof (multiplier_array) + MULTIPLIER_RANDOMS  
  1433.     : 1)
  1434. #define MULTIPLIER_ITERATION                                            
  1435.   ARRAY_ITERATION(multiplier, multiplier_index, MULTIPLIER_COUNT,       
  1436.   multiplier_array, MULTIPLIER_RANDOMS, TRY_MULTIPLIER)
  1437. #define DIVISOR_COUNT                           
  1438.   (tr->divisor                                  
  1439.    ? numberof (divisor_array) + DIVISOR_RANDOMS 
  1440.    : 1)
  1441. #define DIVISOR_ITERATION                                               
  1442.   ARRAY_ITERATION(divisor, divisor_index, DIVISOR_COUNT, divisor_array, 
  1443.   DIVISOR_RANDOMS, TRY_DIVISOR)
  1444. /* overlap_array[].s[i] is where s[i] should be, 0 or 1 means overlapping
  1445.    d[0] or d[1] respectively, -1 means a separate (write-protected)
  1446.    location. */
  1447. struct overlap_t {
  1448.   int  s[NUM_SOURCES];
  1449. } overlap_array[] = {
  1450.   { { -1, -1 } },
  1451.   { {  0, -1 } },
  1452.   { { -1,  0 } },
  1453.   { {  0,  0 } },
  1454.   { {  1, -1 } },
  1455.   { { -1,  1 } },
  1456.   { {  1,  1 } },
  1457.   { {  0,  1 } },
  1458.   { {  1,  0 } },
  1459. };
  1460. struct overlap_t  *overlap, *overlap_limit;
  1461. #define OVERLAP_COUNT                   
  1462.   (tr->overlap & OVERLAP_NONE       ? 1 
  1463.    : tr->overlap & OVERLAP_NOT_SRCS ? 3 
  1464.    : tr->overlap & OVERLAP_NOT_SRC2 ? 2 
  1465.    : tr->dst[1]                     ? 9 
  1466.    : tr->src[1]                     ? 4 
  1467.    : tr->dst[0]                     ? 2 
  1468.    : 1)
  1469. #define OVERLAP_ITERATION                               
  1470.   for (overlap = &overlap_array[0],                     
  1471.     overlap_limit = &overlap_array[OVERLAP_COUNT];      
  1472.     overlap < overlap_limit;                            
  1473.     overlap++)
  1474. int  base = 10;
  1475. #define T_RAND_COUNT  2
  1476. int  t_rand;
  1477. void
  1478. t_random (mp_ptr ptr, mp_size_t n)
  1479. {
  1480.   if (n == 0)
  1481.     return;
  1482.   switch (option_data) {
  1483.   case DATA_TRAND:
  1484.     switch (t_rand) {
  1485.     case 0: refmpn_random (ptr, n); break;
  1486.     case 1: refmpn_random2 (ptr, n); break;
  1487.     default: abort();
  1488.     }
  1489.     break;
  1490.   case DATA_SEQ:
  1491.     {
  1492.       static mp_limb_t  counter = 0;
  1493.       mp_size_t  i;
  1494.       for (i = 0; i < n; i++)
  1495. ptr[i] = ++counter;
  1496.     }
  1497.     break;
  1498.   case DATA_ZEROS:
  1499.     refmpn_zero (ptr, n);
  1500.     break;
  1501.   case DATA_FFS:
  1502.     refmpn_fill (ptr, n, GMP_NUMB_MAX);
  1503.     break;
  1504.   case DATA_2FD:
  1505.     /* Special value 0x2FFF...FFFD, which divided by 3 gives 0xFFF...FFF,
  1506.        inducing the q1_ff special case in the mul-by-inverse part of some
  1507.        versions of divrem_1 and mod_1. */
  1508.     refmpn_fill (ptr, n, (mp_limb_t) -1);
  1509.     ptr[n-1] = 2;
  1510.     ptr[0] -= 2;
  1511.     break;
  1512.   default:
  1513.     abort();
  1514.   }
  1515. }
  1516. #define T_RAND_ITERATION 
  1517.   for (t_rand = 0; t_rand < T_RAND_COUNT; t_rand++)
  1518. void
  1519. print_each (const struct each_t *e)
  1520. {
  1521.   int  i;
  1522.   printf ("%s %sn", e->name, e == &ref ? tr->reference_name : choice->name);
  1523.   if (tr->retval)
  1524.     mpn_trace ("   retval", &e->retval, 1);
  1525.   for (i = 0; i < NUM_DESTS; i++)
  1526.     {
  1527.       if (tr->dst[i])
  1528. {
  1529.   if (tr->dst_bytes[i])
  1530.     byte_tracen ("   d[%d]", i, e->d[i].p, d[i].size);
  1531.   else
  1532.     mpn_tracen ("   d[%d]", i, e->d[i].p, d[i].size);
  1533.   printf ("        located %pn", (void *) (e->d[i].p));
  1534. }
  1535.     }
  1536.   for (i = 0; i < NUM_SOURCES; i++)
  1537.     if (tr->src[i])
  1538.       printf ("   s[%d] located %pn", i, (void *)  (e->s[i].p));
  1539. }
  1540. void
  1541. print_all (void)
  1542. {
  1543.   int  i;
  1544.   printf ("n");
  1545.   printf ("size  %ldn", (long) size);
  1546.   if (tr->size2)
  1547.     printf ("size2 %ldn", (long) size2);
  1548.   for (i = 0; i < NUM_DESTS; i++)
  1549.     if (d[i].size != size)
  1550.       printf ("d[%d].size %ldn", i, (long) d[i].size);
  1551.   if (tr->multiplier)
  1552.     mpn_trace ("   multiplier", &multiplier, 1);
  1553.   if (tr->divisor)
  1554.     mpn_trace ("   divisor", &divisor, 1);
  1555.   if (tr->shift)
  1556.     printf ("   shift %lun", shift);
  1557.   if (tr->carry)
  1558.     mpn_trace ("   carry", &carry, 1);
  1559.   if (tr->msize)
  1560.     mpn_trace ("   multiplier_N", multiplier_N, tr->msize);
  1561.   for (i = 0; i < NUM_DESTS; i++)
  1562.     if (tr->dst[i])
  1563.       printf ("   d[%d] %s, align %ld, size %ldn",
  1564.       i, d[i].high ? "high" : "low",
  1565.       (long) d[i].align, (long) d[i].size);
  1566.   for (i = 0; i < NUM_SOURCES; i++)
  1567.     {
  1568.       if (tr->src[i])
  1569. {
  1570.   printf ("   s[%d] %s, align %ld, ",
  1571.   i, s[i].high ? "high" : "low", (long) s[i].align);
  1572.   switch (overlap->s[i]) {
  1573.   case -1:
  1574.     printf ("no overlapn");
  1575.     break;
  1576.   default:
  1577.     printf ("==d[%d]%sn",
  1578.     overlap->s[i],
  1579.     tr->overlap == OVERLAP_LOW_TO_HIGH ? "+a"
  1580.     : tr->overlap == OVERLAP_HIGH_TO_LOW ? "-a"
  1581.     : "");
  1582.     break;
  1583.   }
  1584.   printf ("   s[%d]=", i);
  1585.   if (tr->carry_sign && (carry & (1 << i)))
  1586.     printf ("-");
  1587.   mpn_trace (NULL, s[i].p, SRC_SIZE(i));
  1588. }
  1589.     }
  1590.   if (tr->dst0_from_src1)
  1591.     mpn_trace ("   d[0]", s[1].region.ptr, size);
  1592.   if (tr->reference)
  1593.     print_each (&ref);
  1594.   print_each (&fun);
  1595. }
  1596. void
  1597. compare (void)
  1598. {
  1599.   int  error = 0;
  1600.   int  i;
  1601.   if (tr->retval && ref.retval != fun.retval)
  1602.     {
  1603.       gmp_printf ("Different return values (%Mu, %Mu)n",
  1604.   ref.retval, fun.retval);
  1605.       error = 1;
  1606.     }
  1607.   for (i = 0; i < NUM_DESTS; i++)
  1608.     {
  1609.       switch (tr->dst_size[i]) {
  1610.       case SIZE_RETVAL:
  1611.       case SIZE_GET_STR:
  1612. d[i].size = ref.retval;
  1613. break;
  1614.       }
  1615.     }
  1616.   for (i = 0; i < NUM_DESTS; i++)
  1617.     {
  1618.       if (! tr->dst[i])
  1619. continue;
  1620.       if (tr->dst_bytes[i])
  1621. {
  1622.   if (memcmp (ref.d[i].p, fun.d[i].p, d[i].size) != 0)
  1623.     {
  1624.       printf ("Different d[%d] data results, low diff at %ld, high diff at %ldn",
  1625.       i,
  1626.       (long) byte_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
  1627.       (long) byte_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
  1628.       error = 1;
  1629.     }
  1630. }
  1631.       else
  1632. {
  1633.   if (d[i].size != 0
  1634.       && ! refmpn_equal_anynail (ref.d[i].p, fun.d[i].p, d[i].size))
  1635.     {
  1636.       printf ("Different d[%d] data results, low diff at %ld, high diff at %ldn",
  1637.       i,
  1638.       (long) mpn_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
  1639.       (long) mpn_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
  1640.       error = 1;
  1641.     }
  1642. }
  1643.     }
  1644.   if (error)
  1645.     {
  1646.       print_all();
  1647.       abort();
  1648.     }
  1649. }
  1650. /* The functions are cast if the return value should be a long rather than
  1651.    the default mp_limb_t.  This is necessary under _LONG_LONG_LIMB.  This
  1652.    might not be enough if some actual calling conventions checking is
  1653.    implemented on a long long limb system.  */
  1654. void
  1655. call (struct each_t *e, tryfun_t function)
  1656. {
  1657.   switch (choice->type) {
  1658.   case TYPE_ADD:
  1659.   case TYPE_SUB:
  1660.     e->retval = CALLING_CONVENTIONS (function)
  1661.       (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
  1662.     break;
  1663.   case TYPE_ADD_N:
  1664.   case TYPE_SUB_N:
  1665.   case TYPE_ADDLSH1_N:
  1666.   case TYPE_ADDLSH2_N:
  1667.   case TYPE_SUBLSH1_N:
  1668.   case TYPE_RSBLSH1_N:
  1669.   case TYPE_RSBLSH2_N:
  1670.   case TYPE_RSH1ADD_N:
  1671.   case TYPE_RSH1SUB_N:
  1672.     e->retval = CALLING_CONVENTIONS (function)
  1673.       (e->d[0].p, e->s[0].p, e->s[1].p, size);
  1674.     break;
  1675.   case TYPE_ADDLSH_N:
  1676.   case TYPE_SUBLSH_N:
  1677.   case TYPE_RSBLSH_N:
  1678.     e->retval = CALLING_CONVENTIONS (function)
  1679.       (e->d[0].p, e->s[0].p, e->s[1].p, size, shift);
  1680.     break;
  1681.   case TYPE_ADD_NC:
  1682.   case TYPE_SUB_NC:
  1683.     e->retval = CALLING_CONVENTIONS (function)
  1684.       (e->d[0].p, e->s[0].p, e->s[1].p, size, carry);
  1685.     break;
  1686.   case TYPE_MUL_1:
  1687.   case TYPE_ADDMUL_1:
  1688.   case TYPE_SUBMUL_1:
  1689.     e->retval = CALLING_CONVENTIONS (function)
  1690.       (e->d[0].p, e->s[0].p, size, multiplier);
  1691.     break;
  1692.   case TYPE_MUL_1C:
  1693.   case TYPE_ADDMUL_1C:
  1694.   case TYPE_SUBMUL_1C:
  1695.     e->retval = CALLING_CONVENTIONS (function)
  1696.       (e->d[0].p, e->s[0].p, size, multiplier, carry);
  1697.     break;
  1698.   case TYPE_MUL_2:
  1699.   case TYPE_MUL_3:
  1700.   case TYPE_MUL_4:
  1701.     if (size == 1)
  1702.       abort ();
  1703.     e->retval = CALLING_CONVENTIONS (function)
  1704.       (e->d[0].p, e->s[0].p, size, multiplier_N);
  1705.     break;
  1706.   case TYPE_ADDMUL_2:
  1707.   case TYPE_ADDMUL_3:
  1708.   case TYPE_ADDMUL_4:
  1709.   case TYPE_ADDMUL_5:
  1710.   case TYPE_ADDMUL_6:
  1711.   case TYPE_ADDMUL_7:
  1712.   case TYPE_ADDMUL_8:
  1713.     if (size == 1)
  1714.       abort ();
  1715.     e->retval = CALLING_CONVENTIONS (function)
  1716.       (e->d[0].p, e->s[0].p, size, multiplier_N);
  1717.     break;
  1718.   case TYPE_AND_N:
  1719.   case TYPE_ANDN_N:
  1720.   case TYPE_NAND_N:
  1721.   case TYPE_IOR_N:
  1722.   case TYPE_IORN_N:
  1723.   case TYPE_NIOR_N:
  1724.   case TYPE_XOR_N:
  1725.   case TYPE_XNOR_N:
  1726.     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
  1727.     break;
  1728.   case TYPE_ADDSUB_N:
  1729.     e->retval = CALLING_CONVENTIONS (function)
  1730.       (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size);
  1731.     break;
  1732.   case TYPE_ADDSUB_NC:
  1733.     e->retval = CALLING_CONVENTIONS (function)
  1734.       (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size, carry);
  1735.     break;
  1736.   case TYPE_COPY:
  1737.   case TYPE_COPYI:
  1738.   case TYPE_COPYD:
  1739.   case TYPE_COM:
  1740.     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
  1741.     break;
  1742.   case TYPE_DIVEXACT_BY3:
  1743.     e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
  1744.     break;
  1745.   case TYPE_DIVEXACT_BY3C:
  1746.     e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size,
  1747. carry);
  1748.     break;
  1749.   case TYPE_DIVMOD_1:
  1750.   case TYPE_DIVEXACT_1:
  1751.     e->retval = CALLING_CONVENTIONS (function)
  1752.       (e->d[0].p, e->s[0].p, size, divisor);
  1753.     break;
  1754.   case TYPE_DIVMOD_1C:
  1755.     e->retval = CALLING_CONVENTIONS (function)
  1756.       (e->d[0].p, e->s[0].p, size, divisor, carry);
  1757.     break;
  1758.   case TYPE_DIVREM_1:
  1759.     e->retval = CALLING_CONVENTIONS (function)
  1760.       (e->d[0].p, size2, e->s[0].p, size, divisor);
  1761.     break;
  1762.   case TYPE_DIVREM_1C:
  1763.     e->retval = CALLING_CONVENTIONS (function)
  1764.       (e->d[0].p, size2, e->s[0].p, size, divisor, carry);
  1765.     break;
  1766.   case TYPE_PREINV_DIVREM_1:
  1767.     {
  1768.       mp_limb_t  dinv;
  1769.       unsigned   shift;
  1770.       shift = refmpn_count_leading_zeros (divisor);
  1771.       dinv = refmpn_invert_limb (divisor << shift);
  1772.       e->retval = CALLING_CONVENTIONS (function)
  1773. (e->d[0].p, size2, e->s[0].p, size, divisor, dinv, shift);
  1774.     }
  1775.     break;
  1776.   case TYPE_MOD_1:
  1777.   case TYPE_MODEXACT_1_ODD:
  1778.     e->retval = CALLING_CONVENTIONS (function)
  1779.       (e->s[0].p, size, divisor);
  1780.     break;
  1781.   case TYPE_MOD_1C:
  1782.   case TYPE_MODEXACT_1C_ODD:
  1783.     e->retval = CALLING_CONVENTIONS (function)
  1784.       (e->s[0].p, size, divisor, carry);
  1785.     break;
  1786.   case TYPE_PREINV_MOD_1:
  1787.     e->retval = CALLING_CONVENTIONS (function)
  1788.       (e->s[0].p, size, divisor, refmpn_invert_limb (divisor));
  1789.     break;
  1790.   case TYPE_MOD_34LSUB1:
  1791.     e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size);
  1792.     break;
  1793.   case TYPE_UDIV_QRNND:
  1794.     e->retval = CALLING_CONVENTIONS (function)
  1795.       (e->d[0].p, e->s[0].p[1], e->s[0].p[0], divisor);
  1796.     break;
  1797.   case TYPE_UDIV_QRNND_R:
  1798.     e->retval = CALLING_CONVENTIONS (function)
  1799.       (e->s[0].p[1], e->s[0].p[0], divisor, e->d[0].p);
  1800.     break;
  1801.   case TYPE_SBPI1_DIV_QR:
  1802.     {
  1803.       gmp_pi1_t dinv;
  1804.       invert_pi1 (dinv, e->s[1].p[size2-1], e->s[1].p[size2-2]); /* FIXME: use refinvert_pi1 */
  1805.       refmpn_copyi (e->d[1].p, e->s[0].p, size);        /* dividend */
  1806.       refmpn_fill (e->d[0].p, size-size2, 0x98765432);  /* quotient */
  1807.       e->retval = CALLING_CONVENTIONS (function)
  1808. (e->d[0].p, e->d[1].p, size, e->s[1].p, size2, dinv.inv32);
  1809.       refmpn_zero (e->d[1].p+size2, size-size2);    /* excess over remainder */
  1810.     }
  1811.     break;
  1812.   case TYPE_TDIV_QR:
  1813.     CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, 0,
  1814.     e->s[0].p, size, e->s[1].p, size2);
  1815.     break;
  1816.   case TYPE_GCD_1:
  1817.     /* Must have a non-zero src, but this probably isn't the best way to do
  1818.        it. */
  1819.     if (refmpn_zero_p (e->s[0].p, size))
  1820.       e->retval = 0;
  1821.     else
  1822.       e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor);
  1823.     break;
  1824.   case TYPE_GCD:
  1825.     /* Sources are destroyed, so they're saved and replaced, but a general
  1826.        approach to this might be better.  Note that it's still e->s[0].p and
  1827.        e->s[1].p that are passed, to get the desired alignments. */
  1828.     {
  1829.       mp_ptr  s0 = refmpn_malloc_limbs (size);
  1830.       mp_ptr  s1 = refmpn_malloc_limbs (size2);
  1831.       refmpn_copyi (s0, e->s[0].p, size);
  1832.       refmpn_copyi (s1, e->s[1].p, size2);
  1833.       mprotect_region (&s[0].region, PROT_READ|PROT_WRITE);
  1834.       mprotect_region (&s[1].region, PROT_READ|PROT_WRITE);
  1835.       e->retval = CALLING_CONVENTIONS (function) (e->d[0].p,
  1836.   e->s[0].p, size,
  1837.   e->s[1].p, size2);
  1838.       refmpn_copyi (e->s[0].p, s0, size);
  1839.       refmpn_copyi (e->s[1].p, s1, size2);
  1840.       free (s0);
  1841.       free (s1);
  1842.     }
  1843.     break;
  1844.   case TYPE_GCD_FINDA:
  1845.     {
  1846.       /* FIXME: do this with a flag */
  1847.       mp_limb_t  c[2];
  1848.       c[0] = e->s[0].p[0];
  1849.       c[0] += (c[0] == 0);
  1850.       c[1] = e->s[0].p[0];
  1851.       c[1] += (c[1] == 0);
  1852.       e->retval = CALLING_CONVENTIONS (function) (c);
  1853.     }
  1854.     break;
  1855.   case TYPE_MPZ_JACOBI:
  1856.   case TYPE_MPZ_KRONECKER:
  1857.     {
  1858.       mpz_t  a, b;
  1859.       PTR(a) = e->s[0].p; SIZ(a) = ((carry&1)==0 ? size : -size);
  1860.       PTR(b) = e->s[1].p; SIZ(b) = ((carry&2)==0 ? size2 : -size2);
  1861.       e->retval = CALLING_CONVENTIONS (function) (a, b);
  1862.     }
  1863.     break;
  1864.   case TYPE_MPZ_KRONECKER_UI:
  1865.     {
  1866.       mpz_t  a;
  1867.       PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
  1868.       e->retval = CALLING_CONVENTIONS(function) (a, (unsigned long)multiplier);
  1869.     }
  1870.     break;
  1871.   case TYPE_MPZ_KRONECKER_SI:
  1872.     {
  1873.       mpz_t  a;
  1874.       PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
  1875.       e->retval = CALLING_CONVENTIONS (function) (a, (long) multiplier);
  1876.     }
  1877.     break;
  1878.   case TYPE_MPZ_UI_KRONECKER:
  1879.     {
  1880.       mpz_t  b;
  1881.       PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
  1882.       e->retval = CALLING_CONVENTIONS(function) ((unsigned long)multiplier, b);
  1883.     }
  1884.     break;
  1885.   case TYPE_MPZ_SI_KRONECKER:
  1886.     {
  1887.       mpz_t  b;
  1888.       PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
  1889.       e->retval = CALLING_CONVENTIONS (function) ((long) multiplier, b);
  1890.     }
  1891.     break;
  1892.   case TYPE_MUL_MN:
  1893.     CALLING_CONVENTIONS (function)
  1894.       (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
  1895.     break;
  1896.   case TYPE_MUL_N:
  1897.   case TYPE_MULLO_N:
  1898.     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
  1899.     break;
  1900.   case TYPE_SQR:
  1901.     CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
  1902.     break;
  1903.   case TYPE_UMUL_PPMM:
  1904.     e->retval = CALLING_CONVENTIONS (function)
  1905.       (e->d[0].p, e->s[0].p[0], e->s[0].p[1]);
  1906.     break;
  1907.   case TYPE_UMUL_PPMM_R:
  1908.     e->retval = CALLING_CONVENTIONS (function)
  1909.       (e->s[0].p[0], e->s[0].p[1], e->d[0].p);
  1910.     break;
  1911.   case TYPE_LSHIFT:
  1912.   case TYPE_LSHIFTC:
  1913.   case TYPE_RSHIFT:
  1914.     e->retval = CALLING_CONVENTIONS (function)
  1915.       (e->d[0].p, e->s[0].p, size, shift);
  1916.     break;
  1917.   case TYPE_POPCOUNT:
  1918.     e->retval = (* (unsigned long (*)(ANYARGS))
  1919.  CALLING_CONVENTIONS (function)) (e->s[0].p, size);
  1920.     break;
  1921.   case TYPE_HAMDIST:
  1922.     e->retval = (* (unsigned long (*)(ANYARGS))
  1923.  CALLING_CONVENTIONS (function)) (e->s[0].p, e->s[1].p, size);
  1924.     break;
  1925.   case TYPE_SQRTREM:
  1926.     e->retval = (* (long (*)(ANYARGS)) CALLING_CONVENTIONS (function))
  1927.       (e->d[0].p, e->d[1].p, e->s[0].p, size);
  1928.     break;
  1929.   case TYPE_ZERO:
  1930.     CALLING_CONVENTIONS (function) (e->d[0].p, size);
  1931.     break;
  1932.   case TYPE_GET_STR:
  1933.     {
  1934.       size_t  sizeinbase, fill;
  1935.       char    *dst;
  1936.       MPN_SIZEINBASE (sizeinbase, e->s[0].p, size, base);
  1937.       ASSERT_ALWAYS (sizeinbase <= d[0].size);
  1938.       fill = d[0].size - sizeinbase;
  1939.       if (d[0].high)
  1940. {
  1941.   memset (e->d[0].p, 0xBA, fill);
  1942.   dst = (char *) e->d[0].p + fill;
  1943. }
  1944.       else
  1945. {
  1946.   dst = (char *) e->d[0].p;
  1947.   memset (dst + sizeinbase, 0xBA, fill);
  1948. }
  1949.       if (POW2_P (base))
  1950. {
  1951.   e->retval = CALLING_CONVENTIONS (function) (dst, base,
  1952.       e->s[0].p, size);
  1953. }
  1954.       else
  1955. {
  1956.   refmpn_copy (e->d[1].p, e->s[0].p, size);
  1957.   e->retval = CALLING_CONVENTIONS (function) (dst, base,
  1958.       e->d[1].p, size);
  1959. }
  1960.       refmpn_zero (e->d[1].p, size);  /* clobbered or unused */
  1961.     }
  1962.     break;
  1963.  case TYPE_INVERT:
  1964.     {
  1965.       mp_ptr scratch;
  1966.       TMP_DECL;
  1967.       TMP_MARK;
  1968.       scratch = TMP_ALLOC_LIMBS (mpn_invert_itch (size));
  1969.       CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
  1970.       TMP_FREE;
  1971.     }
  1972.     break;
  1973.   case TYPE_BINVERT:
  1974.     {
  1975.       mp_ptr scratch;
  1976.       TMP_DECL;
  1977.       TMP_MARK;
  1978.       scratch = TMP_ALLOC_LIMBS (mpn_binvert_itch (size));
  1979.       CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
  1980.       TMP_FREE;
  1981.     }
  1982.     break;
  1983. #ifdef EXTRA_CALL
  1984.     EXTRA_CALL
  1985. #endif
  1986.   default:
  1987.     printf ("Unknown routine type %dn", choice->type);
  1988.     abort ();
  1989.     break;
  1990.   }
  1991. }
  1992. void
  1993. pointer_setup (struct each_t *e)
  1994. {
  1995.   int  i, j;
  1996.   for (i = 0; i < NUM_DESTS; i++)
  1997.     {
  1998.       switch (tr->dst_size[i]) {
  1999.       case 0:
  2000.       case SIZE_RETVAL: /* will be adjusted later */
  2001. d[i].size = size;
  2002. break;
  2003.       case SIZE_1:
  2004. d[i].size = 1;
  2005. break;
  2006.       case SIZE_2:
  2007. d[i].size = 2;
  2008. break;
  2009.       case SIZE_3:
  2010. d[i].size = 3;
  2011. break;
  2012.       case SIZE_PLUS_1:
  2013. d[i].size = size+1;
  2014. break;
  2015.       case SIZE_PLUS_MSIZE_SUB_1:
  2016. d[i].size = size + tr->msize - 1;
  2017. break;
  2018.       case SIZE_SUM:
  2019. if (tr->size2)
  2020.   d[i].size = size + size2;
  2021. else
  2022.   d[i].size = 2*size;
  2023. break;
  2024.       case SIZE_SIZE2:
  2025. d[i].size = size2;
  2026. break;
  2027.       case SIZE_DIFF:
  2028. d[i].size = size - size2;
  2029. break;
  2030.       case SIZE_DIFF_PLUS_1:
  2031. d[i].size = size - size2 + 1;
  2032. break;
  2033.       case SIZE_CEIL_HALF:
  2034. d[i].size = (size+1)/2;
  2035. break;
  2036.       case SIZE_GET_STR:
  2037. {
  2038.   mp_limb_t ff = GMP_NUMB_MAX;
  2039.   MPN_SIZEINBASE (d[i].size, &ff - (size-1), size, base);
  2040. }
  2041. break;
  2042.       default:
  2043. printf ("Unrecognised dst_size type %dn", tr->dst_size[i]);
  2044. abort ();
  2045.       }
  2046.     }
  2047.   /* establish e->d[].p destinations */
  2048.   for (i = 0; i < NUM_DESTS; i++)
  2049.     {
  2050.       mp_size_t  offset = 0;
  2051.       /* possible room for overlapping sources */
  2052.       for (j = 0; j < numberof (overlap->s); j++)
  2053. if (overlap->s[j] == i)
  2054.   offset = MAX (offset, s[j].align);
  2055.       if (d[i].high)
  2056. {
  2057.   if (tr->dst_bytes[i])
  2058.     {
  2059.       e->d[i].p = (mp_ptr)
  2060. ((char *) (e->d[i].region.ptr + e->d[i].region.size)
  2061.  - d[i].size - d[i].align);
  2062.     }
  2063.   else
  2064.     {
  2065.       e->d[i].p = e->d[i].region.ptr + e->d[i].region.size
  2066. - d[i].size - d[i].align;
  2067.       if (tr->overlap == OVERLAP_LOW_TO_HIGH)
  2068. e->d[i].p -= offset;
  2069.     }
  2070. }
  2071.       else
  2072. {
  2073.   if (tr->dst_bytes[i])
  2074.     {
  2075.       e->d[i].p = (mp_ptr) ((char *) e->d[i].region.ptr + d[i].align);
  2076.     }
  2077.   else
  2078.     {
  2079.       e->d[i].p = e->d[i].region.ptr + d[i].align;
  2080.       if (tr->overlap == OVERLAP_HIGH_TO_LOW)
  2081. e->d[i].p += offset;
  2082.     }
  2083. }
  2084.     }
  2085.   /* establish e->s[].p sources */
  2086.   for (i = 0; i < NUM_SOURCES; i++)
  2087.     {
  2088.       int  o = overlap->s[i];
  2089.       switch (o) {
  2090.       case -1:
  2091. /* no overlap */
  2092. e->s[i].p = s[i].p;
  2093. break;
  2094.       case 0:
  2095.       case 1:
  2096. /* overlap with d[o] */
  2097. if (tr->overlap == OVERLAP_HIGH_TO_LOW)
  2098.   e->s[i].p = e->d[o].p - s[i].align;
  2099. else if (tr->overlap == OVERLAP_LOW_TO_HIGH)
  2100.   e->s[i].p = e->d[o].p + s[i].align;
  2101. else if (tr->size2 == SIZE_FRACTION)
  2102.   e->s[i].p = e->d[o].p + size2;
  2103. else
  2104.   e->s[i].p = e->d[o].p;
  2105. break;
  2106.       default:
  2107. abort();
  2108. break;
  2109.       }
  2110.     }
  2111. }
  2112. void
  2113. validate_fail (void)
  2114. {
  2115.   if (tr->reference)
  2116.     {
  2117.       trap_location = TRAP_REF;
  2118.       call (&ref, tr->reference);
  2119.       trap_location = TRAP_NOWHERE;
  2120.     }
  2121.   print_all();
  2122.   abort();
  2123. }
  2124. void
  2125. try_one (void)
  2126. {
  2127.   int  i;
  2128.   if (option_spinner)
  2129.     spinner();
  2130.   spinner_count++;
  2131.   trap_location = TRAP_SETUPS;
  2132.   if (tr->divisor == DIVISOR_NORM)
  2133.     divisor |= GMP_NUMB_HIGHBIT;
  2134.   if (tr->divisor == DIVISOR_ODD)
  2135.     divisor |= 1;
  2136.   for (i = 0; i < NUM_SOURCES; i++)
  2137.     {
  2138.       if (s[i].high)
  2139. s[i].p = s[i].region.ptr + s[i].region.size - SRC_SIZE(i) - s[i].align;
  2140.       else
  2141. s[i].p = s[i].region.ptr + s[i].align;
  2142.     }
  2143.   pointer_setup (&ref);
  2144.   pointer_setup (&fun);
  2145.   ref.retval = 0x04152637;
  2146.   fun.retval = 0x8C9DAEBF;
  2147.   t_random (multiplier_N, tr->msize);
  2148.   for (i = 0; i < NUM_SOURCES; i++)
  2149.     {
  2150.       if (! tr->src[i])
  2151. continue;
  2152.       mprotect_region (&s[i].region, PROT_READ|PROT_WRITE);
  2153.       t_random (s[i].p, SRC_SIZE(i));
  2154.       switch (tr->data) {
  2155.       case DATA_NON_ZERO:
  2156. if (refmpn_zero_p (s[i].p, SRC_SIZE(i)))
  2157.   s[i].p[0] = 1;
  2158. break;
  2159.       case DATA_MULTIPLE_DIVISOR:
  2160. /* same number of low zero bits as divisor */
  2161. s[i].p[0] &= ~ LOW_ZEROS_MASK (divisor);
  2162. refmpn_sub_1 (s[i].p, s[i].p, size,
  2163.       refmpn_mod_1 (s[i].p, size, divisor));
  2164. break;
  2165.       case DATA_GCD:
  2166. /* s[1] no more bits than s[0] */
  2167. if (i == 1 && size2 == size)
  2168.   s[1].p[size-1] &= refmpn_msbone_mask (s[0].p[size-1]);
  2169. /* high limb non-zero */
  2170. s[i].p[SRC_SIZE(i)-1] += (s[i].p[SRC_SIZE(i)-1] == 0);
  2171. /* odd */
  2172. s[i].p[0] |= 1;
  2173. break;
  2174.       case DATA_SRC0_ODD:
  2175. if (i == 0)
  2176.   s[i].p[0] |= 1;
  2177. break;
  2178.       case DATA_SRC1_ODD:
  2179. if (i == 1)
  2180.   s[i].p[0] |= 1;
  2181. break;
  2182.       case DATA_SRC1_HIGHBIT:
  2183. if (i == 1)
  2184.   {
  2185.     if (tr->size2)
  2186.       s[i].p[size2-1] |= GMP_NUMB_HIGHBIT;
  2187.     else
  2188.       s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
  2189.   }
  2190. break;
  2191.       case DATA_SRC0_HIGHBIT:
  2192.        if (i == 0)
  2193.          {
  2194.            s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
  2195.          }
  2196.        break;
  2197.       case DATA_UDIV_QRNND:
  2198. s[i].p[1] %= divisor;
  2199. break;
  2200.       }
  2201.       mprotect_region (&s[i].region, PROT_READ);
  2202.     }
  2203.   for (i = 0; i < NUM_DESTS; i++)
  2204.     {
  2205.       if (! tr->dst[i])
  2206. continue;
  2207.       if (tr->dst0_from_src1 && i==0)
  2208. {
  2209.   mp_size_t  copy = MIN (d[0].size, SRC_SIZE(1));
  2210.   mp_size_t  fill = MAX (0, d[0].size - copy);
  2211.   MPN_COPY (fun.d[0].p, s[1].region.ptr, copy);
  2212.   MPN_COPY (ref.d[0].p, s[1].region.ptr, copy);
  2213.   refmpn_fill (fun.d[0].p + copy, fill, DEADVAL);
  2214.   refmpn_fill (ref.d[0].p + copy, fill, DEADVAL);
  2215. }
  2216.       else if (tr->dst_bytes[i])
  2217. {
  2218.   memset (ref.d[i].p, 0xBA, d[i].size);
  2219.   memset (fun.d[i].p, 0xBA, d[i].size);
  2220. }
  2221.       else
  2222. {
  2223.   refmpn_fill (ref.d[i].p, d[i].size, DEADVAL);
  2224.   refmpn_fill (fun.d[i].p, d[i].size, DEADVAL);
  2225. }
  2226.     }
  2227.   for (i = 0; i < NUM_SOURCES; i++)
  2228.     {
  2229.       if (! tr->src[i])
  2230. continue;
  2231.       if (ref.s[i].p != s[i].p)
  2232. {
  2233.   refmpn_copyi (ref.s[i].p, s[i].p, SRC_SIZE(i));
  2234.   refmpn_copyi (fun.s[i].p, s[i].p, SRC_SIZE(i));
  2235. }
  2236.     }
  2237.   if (option_print)
  2238.     print_all();
  2239.   if (tr->validate != NULL)
  2240.     {
  2241.       trap_location = TRAP_FUN;
  2242.       call (&fun, choice->function);
  2243.       trap_location = TRAP_NOWHERE;
  2244.       if (! CALLING_CONVENTIONS_CHECK ())
  2245. {
  2246.   print_all();
  2247.   abort();
  2248. }
  2249.       (*tr->validate) ();
  2250.     }
  2251.   else
  2252.     {
  2253.       trap_location = TRAP_REF;
  2254.       call (&ref, tr->reference);
  2255.       trap_location = TRAP_FUN;
  2256.       call (&fun, choice->function);
  2257.       trap_location = TRAP_NOWHERE;
  2258.       if (! CALLING_CONVENTIONS_CHECK ())
  2259. {
  2260.   print_all();
  2261.   abort();
  2262. }
  2263.       compare ();
  2264.     }
  2265. }
  2266. #define SIZE_ITERATION                                          
  2267.   for (size = MAX3 (option_firstsize,                           
  2268.     choice->minsize,                            
  2269.     (tr->size == SIZE_ALLOW_ZERO) ? 0 : 1);     
  2270.        size <= option_lastsize;                                 
  2271.        size++)
  2272. #define SIZE2_FIRST                                     
  2273.   (tr->size2 == SIZE_2 ? 2                              
  2274.    : tr->size2 == SIZE_FRACTION ? option_firstsize2     
  2275.    : tr->size2 ?                                        
  2276.    MAX (choice->minsize, (option_firstsize2 != 0        
  2277.   ? option_firstsize2 : 1))     
  2278.    : 0)
  2279. #define SIZE2_LAST                                      
  2280.   (tr->size2 == SIZE_2 ? 2                              
  2281.    : tr->size2 == SIZE_FRACTION ? FRACTION_COUNT-1      
  2282.    : tr->size2 ? size                                   
  2283.    : 0)
  2284. #define SIZE2_ITERATION 
  2285.   for (size2 = SIZE2_FIRST; size2 <= SIZE2_LAST; size2++)
  2286. #define ALIGN_COUNT(cond)  ((cond) ? ALIGNMENTS : 1)
  2287. #define ALIGN_ITERATION(w,n,cond) 
  2288.   for (w[n].align = 0; w[n].align < ALIGN_COUNT(cond); w[n].align++)
  2289. #define HIGH_LIMIT(cond)  ((cond) != 0)
  2290. #define HIGH_COUNT(cond)  (HIGH_LIMIT (cond) + 1)
  2291. #define HIGH_ITERATION(w,n,cond) 
  2292.   for (w[n].high = 0; w[n].high <= HIGH_LIMIT(cond); w[n].high++)
  2293. #define SHIFT_LIMIT                                     
  2294.   ((unsigned long) (tr->shift ? GMP_NUMB_BITS -1 : 1))
  2295. #define SHIFT_ITERATION                                 
  2296.   for (shift = 1; shift <= SHIFT_LIMIT; shift++)
  2297. void
  2298. try_many (void)
  2299. {
  2300.   int   i;
  2301.   {
  2302.     unsigned long  total = 1;
  2303.     total *= option_repetitions;
  2304.     total *= option_lastsize;
  2305.     if (tr->size2 == SIZE_FRACTION) total *= FRACTION_COUNT;
  2306.     else if (tr->size2)             total *= (option_lastsize+1)/2;
  2307.     total *= SHIFT_LIMIT;
  2308.     total *= MULTIPLIER_COUNT;
  2309.     total *= DIVISOR_COUNT;
  2310.     total *= CARRY_COUNT;
  2311.     total *= T_RAND_COUNT;
  2312.     total *= HIGH_COUNT (tr->dst[0]);
  2313.     total *= HIGH_COUNT (tr->dst[1]);
  2314.     total *= HIGH_COUNT (tr->src[0]);
  2315.     total *= HIGH_COUNT (tr->src[1]);
  2316.     total *= ALIGN_COUNT (tr->dst[0]);
  2317.     total *= ALIGN_COUNT (tr->dst[1]);
  2318.     total *= ALIGN_COUNT (tr->src[0]);
  2319.     total *= ALIGN_COUNT (tr->src[1]);
  2320.     total *= OVERLAP_COUNT;
  2321.     printf ("%s %lun", choice->name, total);
  2322.   }
  2323.   spinner_count = 0;
  2324.   for (i = 0; i < option_repetitions; i++)
  2325.     SIZE_ITERATION
  2326.       SIZE2_ITERATION
  2327.       SHIFT_ITERATION
  2328.       MULTIPLIER_ITERATION
  2329.       DIVISOR_ITERATION
  2330.       CARRY_ITERATION /* must be after divisor */
  2331.       T_RAND_ITERATION
  2332.       HIGH_ITERATION(d,0, tr->dst[0])
  2333.       HIGH_ITERATION(d,1, tr->dst[1])
  2334.       HIGH_ITERATION(s,0, tr->src[0])
  2335.       HIGH_ITERATION(s,1, tr->src[1])
  2336.       ALIGN_ITERATION(d,0, tr->dst[0])
  2337.       ALIGN_ITERATION(d,1, tr->dst[1])
  2338.       ALIGN_ITERATION(s,0, tr->src[0])
  2339.       ALIGN_ITERATION(s,1, tr->src[1])
  2340.       OVERLAP_ITERATION
  2341.       try_one();
  2342.   printf("n");
  2343. }
  2344. /* Usually print_all() doesn't show much, but it might give a hint as to
  2345.    where the function was up to when it died. */
  2346. void
  2347. trap (int sig)
  2348. {
  2349.   const char *name = "noname";
  2350.   switch (sig) {
  2351.   case SIGILL:  name = "SIGILL";  break;
  2352. #ifdef SIGBUS
  2353.   case SIGBUS:  name = "SIGBUS";  break;
  2354. #endif
  2355.   case SIGSEGV: name = "SIGSEGV"; break;
  2356.   case SIGFPE:  name = "SIGFPE";  break;
  2357.   }
  2358.   printf ("nnSIGNAL TRAP: %sn", name);
  2359.   switch (trap_location) {
  2360.   case TRAP_REF:
  2361.     printf ("  in reference function: %sn", tr->reference_name);
  2362.     break;
  2363.   case TRAP_FUN:
  2364.     printf ("  in test function: %sn", choice->name);
  2365.     print_all ();
  2366.     break;
  2367.   case TRAP_SETUPS:
  2368.     printf ("  in parameter setupsn");
  2369.     print_all ();
  2370.     break;
  2371.   default:
  2372.     printf ("  somewhere unknownn");
  2373.     break;
  2374.   }
  2375.   exit (1);
  2376. }
  2377. void
  2378. try_init (void)
  2379. {
  2380. #if HAVE_GETPAGESIZE
  2381.   /* Prefer getpagesize() over sysconf(), since on SunOS 4 sysconf() doesn't
  2382.      know _SC_PAGESIZE. */
  2383.   pagesize = getpagesize ();
  2384. #else
  2385. #if HAVE_SYSCONF
  2386.   if ((pagesize = sysconf (_SC_PAGESIZE)) == -1)
  2387.     {
  2388.       /* According to the linux man page, sysconf doesn't set errno */
  2389.       fprintf (stderr, "Cannot get sysconf _SC_PAGESIZEn");
  2390.       exit (1);
  2391.     }
  2392. #else
  2393. Error, error, cannot get page size
  2394. #endif
  2395. #endif
  2396.   printf ("pagesize is 0x%lX bytesn", pagesize);
  2397.   signal (SIGILL,  trap);
  2398. #ifdef SIGBUS
  2399.   signal (SIGBUS,  trap);
  2400. #endif
  2401.   signal (SIGSEGV, trap);
  2402.   signal (SIGFPE,  trap);
  2403.   {
  2404.     int  i;
  2405.     for (i = 0; i < NUM_SOURCES; i++)
  2406.       {
  2407. malloc_region (&s[i].region, 2*option_lastsize+ALIGNMENTS-1);
  2408. printf ("s[%d] %p to %p (0x%lX bytes)n",
  2409. i, (void *) (s[i].region.ptr),
  2410. (void *) (s[i].region.ptr + s[i].region.size),
  2411. (long) s[i].region.size * BYTES_PER_MP_LIMB);
  2412.       }
  2413. #define INIT_EACH(e,es)                                                 
  2414.     for (i = 0; i < NUM_DESTS; i++)                                     
  2415.       {                                                                 
  2416. malloc_region (&e.d[i].region, 2*option_lastsize+ALIGNMENTS-1); 
  2417. printf ("%s d[%d] %p to %p (0x%lX bytes)n",                    
  2418. es, i, (void *) (e.d[i].region.ptr),
  2419. (void *)  (e.d[i].region.ptr + e.d[i].region.size),
  2420. (long) e.d[i].region.size * BYTES_PER_MP_LIMB);         
  2421.       }
  2422.     INIT_EACH(ref, "ref");
  2423.     INIT_EACH(fun, "fun");
  2424.   }
  2425. }
  2426. int
  2427. strmatch_wild (const char *pattern, const char *str)
  2428. {
  2429.   size_t  plen, slen;
  2430.   /* wildcard at start */
  2431.   if (pattern[0] == '*')
  2432.     {
  2433.       pattern++;
  2434.       plen = strlen (pattern);
  2435.       slen = strlen (str);
  2436.       return (plen == 0
  2437.       || (slen >= plen && memcmp (pattern, str+slen-plen, plen) == 0));
  2438.     }
  2439.   /* wildcard at end */
  2440.   plen = strlen (pattern);
  2441.   if (plen >= 1 && pattern[plen-1] == '*')
  2442.     return (memcmp (pattern, str, plen-1) == 0);
  2443.   /* no wildcards */
  2444.   return (strcmp (pattern, str) == 0);
  2445. }
  2446. void
  2447. try_name (const char *name)
  2448. {
  2449.   int  found = 0;
  2450.   int  i;
  2451.   for (i = 0; i < numberof (choice_array); i++)
  2452.     {
  2453.       if (strmatch_wild (name, choice_array[i].name))
  2454. {
  2455.   choice = &choice_array[i];
  2456.   tr = &param[choice->type];
  2457.   try_many ();
  2458.   found = 1;
  2459. }
  2460.     }
  2461.   if (!found)
  2462.     {
  2463.       printf ("%s unknownn", name);
  2464.       /* exit (1); */
  2465.     }
  2466. }
  2467. void
  2468. usage (const char *prog)
  2469. {
  2470.   int  col = 0;
  2471.   int  i;
  2472.   printf ("Usage: %s [options] function...n", prog);
  2473.   printf ("    -1        use limb data 1,2,3,etcn");
  2474.   printf ("    -9        use limb data all 0xFF..FFsn");
  2475.   printf ("    -a zeros  use limb data all zerosn");
  2476.   printf ("    -a ffs    use limb data all 0xFF..FFs (same as -9)n");
  2477.   printf ("    -a 2fd    use data 0x2FFF...FFFDn");
  2478.   printf ("    -p        print each case tried (try this if seg faulting)n");
  2479.   printf ("    -R        seed random numbers from time()n");
  2480.   printf ("    -r reps   set repetitions (default %d)n", DEFAULT_REPETITIONS);
  2481.   printf ("    -s size   starting size to testn");
  2482.   printf ("    -S size2  starting size2 to testn");
  2483.   printf ("    -s s1-s2  range of sizes to testn");
  2484.   printf ("    -W        don't show the spinner (use this in gdb)n");
  2485.   printf ("    -z        disable mprotect() redzonesn");
  2486.   printf ("Default data is refmpn_random() and refmpn_random2().n");
  2487.   printf ("n");
  2488.   printf ("Functions that can be tested:n");
  2489.   for (i = 0; i < numberof (choice_array); i++)
  2490.     {
  2491.       if (col + 1 + strlen (choice_array[i].name) > 79)
  2492. {
  2493.   printf ("n");
  2494.   col = 0;
  2495. }
  2496.       printf (" %s", choice_array[i].name);
  2497.       col += 1 + strlen (choice_array[i].name);
  2498.     }
  2499.   printf ("n");
  2500.   exit(1);
  2501. }
  2502. int
  2503. main (int argc, char *argv[])
  2504. {
  2505.   int  i;
  2506.   /* unbuffered output */
  2507.   setbuf (stdout, NULL);
  2508.   setbuf (stderr, NULL);
  2509.   /* default trace in hex, and in upper-case so can paste into bc */
  2510.   mp_trace_base = -16;
  2511.   param_init ();
  2512.   {
  2513.     unsigned long  seed = 123;
  2514.     int   opt;
  2515.     while ((opt = getopt(argc, argv, "19a:b:E:pRr:S:s:Wz")) != EOF)
  2516.       {
  2517. switch (opt) {
  2518. case '1':
  2519.   /* use limb data values 1, 2, 3, ... etc */
  2520.   option_data = DATA_SEQ;
  2521.   break;
  2522. case '9':
  2523.   /* use limb data values 0xFFF...FFF always */
  2524.   option_data = DATA_FFS;
  2525.   break;
  2526. case 'a':
  2527.   if (strcmp (optarg, "zeros") == 0)     option_data = DATA_ZEROS;
  2528.   else if (strcmp (optarg, "seq") == 0)  option_data = DATA_SEQ;
  2529.   else if (strcmp (optarg, "ffs") == 0)  option_data = DATA_FFS;
  2530.   else if (strcmp (optarg, "2fd") == 0)  option_data = DATA_2FD;
  2531.   else
  2532.     {
  2533.       fprintf (stderr, "unrecognised data option: %sn", optarg);
  2534.       exit (1);
  2535.     }
  2536.   break;
  2537. case 'b':
  2538.   mp_trace_base = atoi (optarg);
  2539.   break;
  2540. case 'E':
  2541.   /* re-seed */
  2542.   sscanf (optarg, "%lu", &seed);
  2543.   printf ("Re-seeding with %lun", seed);
  2544.   break;
  2545. case 'p':
  2546.   option_print = 1;
  2547.   break;
  2548. case 'R':
  2549.   /* randomize */
  2550.   seed = time (NULL);
  2551.   printf ("Seeding with %lu, re-run using "-E %lu"n", seed, seed);
  2552.   break;
  2553. case 'r':
  2554.   option_repetitions = atoi (optarg);
  2555.   break;
  2556. case 's':
  2557.   {
  2558.     char  *p;
  2559.     option_firstsize = strtol (optarg, 0, 0);
  2560.     if ((p = strchr (optarg, '-')) != NULL)
  2561.       option_lastsize = strtol (p+1, 0, 0);
  2562.   }
  2563.   break;
  2564. case 'S':
  2565.   /* -S <size> sets the starting size for the second of a two size
  2566.      routine (like mpn_mul_basecase) */
  2567.   option_firstsize2 = strtol (optarg, 0, 0);
  2568.   break;
  2569. case 'W':
  2570.   /* use this when running in the debugger */
  2571.   option_spinner = 0;
  2572.   break;
  2573. case 'z':
  2574.   /* disable redzones */
  2575.   option_redzones = 0;
  2576.   break;
  2577. case '?':
  2578.   usage (argv[0]);
  2579.   break;
  2580. }
  2581.       }
  2582.     gmp_randinit_default (__gmp_rands);
  2583.     __gmp_rands_initialized = 1;
  2584.     gmp_randseed_ui (__gmp_rands, seed);
  2585.   }
  2586.   try_init();
  2587.   if (argc <= optind)
  2588.     usage (argv[0]);
  2589.   for (i = optind; i < argc; i++)
  2590.     try_name (argv[i]);
  2591.   return 0;
  2592. }