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