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