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