[BACK]Return to try.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests / devel

Annotation of OpenXM_contrib/gmp/tests/devel/try.c, Revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>