[BACK]Return to speed.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tune

Annotation of OpenXM_contrib/gmp/tune/speed.h, Revision 1.1.1.1

1.1       maekawa     1: /* Header for speed and threshold things. */
                      2:
                      3: /*
                      4: Copyright (C) 1999, 2000 Free Software Foundation, Inc.
                      5:
                      6: This file is part of the GNU MP Library.
                      7:
                      8: The GNU MP Library is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU Lesser General Public License as published by
                     10: the Free Software Foundation; either version 2.1 of the License, or (at your
                     11: option) any later version.
                     12:
                     13: The GNU MP Library is distributed in the hope that it will be useful, but
                     14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     16: License for more details.
                     17:
                     18: You should have received a copy of the GNU Lesser General Public License
                     19: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     21: MA 02111-1307, USA.
                     22: */
                     23:
                     24: #ifndef __SPEED_H__
                     25: #define __SPEED_H__
                     26:
                     27:
                     28: /* sizes of temporary space required */
                     29: #define MPN_KARA_MUL_N_TSIZE(n)  (2*((n)+BITS_PER_MP_LIMB))
                     30: #define MPN_KARA_SQR_N_TSIZE(n)  (2*((n)+BITS_PER_MP_LIMB))
                     31: #define MPN_TOOM3_MUL_N_TSIZE(n) (2*(n) + 3*BITS_PER_MP_LIMB)
                     32: #define MPN_TOOM3_SQR_N_TSIZE(n) (2*((n) + BITS_PER_MP_LIMB))
                     33:
                     34:
                     35: /* Pad ptr,oldsize with zero limbs (at the most significant end) to make it
                     36:    newsize long. */
                     37: #define MPN_ZERO_EXTEND(ptr, oldsize, newsize)          \
                     38:   do {                                                  \
                     39:     ASSERT ((newsize) >= (oldsize));                    \
                     40:     MPN_ZERO ((ptr)+(oldsize), (newsize)-(oldsize));    \
                     41:   } while (0)
                     42:
                     43: /* A mask of the least significant n bits.  Note 1<<32 doesn't give zero on
                     44:    x86 family CPUs, hence the separate case for BITS_PER_MP_LIMB. */
                     45: #define MP_LIMB_T_LOWBITMASK(n) \
                     46:   ((n) == BITS_PER_MP_LIMB ? MP_LIMB_T_MAX : ((mp_limb_t) 1 << (n)) - 1)
                     47:
                     48:
                     49: /* align must be a power of 2 here, usually CACHE_LINE_SIZE is a good choice */
                     50:
                     51: #define TMP_ALLOC_ALIGNED(bytes, align) \
                     52:   align_pointer (TMP_ALLOC ((bytes) + (align)-1), (align))
                     53: #define TMP_ALLOC_LIMBS_ALIGNED(limbs, align) \
                     54:   ((mp_ptr) TMP_ALLOC_ALIGNED ((limbs)*sizeof(mp_limb_t), align))
                     55:
                     56: /* 32 for pentium, 64 for athlon, might want to configure this for other
                     57:    CPUs.  In truth though nothing has yet shown up that cares about cache
                     58:    line boundaries.  The only practical effect of this is to restrict the
                     59:    range that s->align_xp can take.  Perhaps this could be a variable
                     60:    instead. */
                     61: #define CACHE_LINE_SIZE    64 /* bytes */
                     62:
                     63: #define SPEED_TMP_ALLOC_ADJUST_MASK  (CACHE_LINE_SIZE/BYTES_PER_MP_LIMB - 1)
                     64:
                     65: #define SPEED_TMP_ALLOC_LIMBS(limbs, align) \
                     66:   (speed_tmp_alloc_adjust             \
                     67:     (TMP_ALLOC_LIMBS((limbs) + SPEED_TMP_ALLOC_ADJUST_MASK), (align)))
                     68:
                     69:
                     70: /* This is the size for s->xp_block and s->yp_block, used in certain
                     71:    routines that want to run across many different data values and use
                     72:    s->size for a different purpose, eg. SPEED_ROUTINE_MPN_GCD_1.
                     73:
                     74:    512 means 2kbytes of data for each of xp_block and yp_block, making 4k
                     75:    total, which should fit easily in any L1 data cache. */
                     76:
                     77: #define SPEED_BLOCK_SIZE   512 /* limbs */
                     78:
                     79:
                     80: extern double  speed_unittime;
                     81: extern double  speed_cycletime;
                     82: extern int     speed_precision;
                     83: extern const char *speed_time_string;
                     84: void speed_time_init _PROTO ((void));
                     85: void speed_starttime _PROTO ((void));
                     86: double speed_endtime _PROTO ((void));
                     87:
                     88: struct speed_params {
                     89:   unsigned   reps;      /* how many times to run the routine */
                     90:   mp_ptr     xp;        /* first argument */
                     91:   mp_ptr     yp;        /* second argument */
                     92:   mp_size_t  size;      /* size of both arguments */
                     93:   long       r;         /* user supplied parameter */
                     94:   mp_size_t  align_xp;  /* alignment of xp */
                     95:   mp_size_t  align_yp;  /* alignment of yp */
                     96:   mp_size_t  align_wp;  /* intended alignment of wp */
                     97:   mp_size_t  align_wp2; /* intended alignment of wp2 */
                     98:   mp_ptr     xp_block;  /* first special SPEED_BLOCK_SIZE block */
                     99:   mp_ptr     yp_block;  /* second special SPEED_BLOCK_SIZE block */
                    100:
                    101:   double     time_divisor; /* optionally set by the speed routine */
                    102:
                    103:   /* used by the cache priming things */
                    104:   int        cache;
                    105:   unsigned   src_num, dst_num;
                    106:   struct {
                    107:     mp_ptr    ptr;
                    108:     mp_size_t size;
                    109:   } src[2], dst[3];
                    110: };
                    111:
                    112: typedef double (*speed_function_t) _PROTO ((struct speed_params *s));
                    113:
                    114: double speed_measure _PROTO ((speed_function_t fun, struct speed_params *s));
                    115:
                    116: /* Prototypes for speed measuring routines */
                    117:
                    118: double speed_malloc_free _PROTO ((struct speed_params *s));
                    119: double speed_malloc_realloc_free _PROTO ((struct speed_params *s));
                    120: double speed_memcpy _PROTO ((struct speed_params *s));
                    121: double speed_modlimb_invert _PROTO ((struct speed_params *s));
                    122: double speed_mp_allocate_free _PROTO ((struct speed_params *s));
                    123: double speed_mp_allocate_reallocate_free _PROTO ((struct speed_params *s));
                    124:
                    125: double speed_mpf_init_clear _PROTO ((struct speed_params *s));
                    126:
                    127: double speed_mpn_add_n _PROTO ((struct speed_params *s));
                    128: double speed_mpn_add_n_self _PROTO ((struct speed_params *s));
                    129: double speed_mpn_add_n_inplace _PROTO ((struct speed_params *s));
                    130: double speed_mpn_and_n _PROTO ((struct speed_params *s));
                    131: double speed_mpn_andn_n _PROTO ((struct speed_params *s));
                    132: double speed_mpn_addmul_1 _PROTO ((struct speed_params *s));
                    133: double speed_mpn_bz_divrem_n _PROTO ((struct speed_params *s));
                    134: double speed_mpn_bz_divrem_sb _PROTO ((struct speed_params *s));
                    135: double speed_mpn_bz_tdiv_qr _PROTO ((struct speed_params *s));
                    136: double speed_MPN_COPY _PROTO ((struct speed_params *s));
                    137: double speed_MPN_COPY_DECR _PROTO ((struct speed_params *s));
                    138: double speed_MPN_COPY_INCR _PROTO ((struct speed_params *s));
                    139: double speed_mpn_divexact_by3 _PROTO ((struct speed_params *s));
                    140: double speed_mpn_divmod_1 _PROTO ((struct speed_params *s));
                    141: double speed_mpn_divrem_1 _PROTO ((struct speed_params *s));
                    142: double speed_mpn_divrem_1f _PROTO ((struct speed_params *s));
                    143: double speed_mpn_divrem_1c _PROTO ((struct speed_params *s));
                    144: double speed_mpn_divrem_1cf _PROTO ((struct speed_params *s));
                    145: double speed_mpn_divrem_2 _PROTO ((struct speed_params *s));
                    146: double speed_mpn_gcd _PROTO ((struct speed_params *s));
                    147: double speed_mpn_gcd_1 _PROTO ((struct speed_params *s));
                    148: double speed_mpn_gcdext _PROTO ((struct speed_params *s));
                    149: double speed_mpn_hamdist _PROTO ((struct speed_params *s));
                    150: double speed_mpn_ior_n _PROTO ((struct speed_params *s));
                    151: double speed_mpn_iorn_n _PROTO ((struct speed_params *s));
                    152: double speed_mpn_jacobi_base _PROTO ((struct speed_params *s));
                    153: double speed_mpn_kara_mul_n _PROTO ((struct speed_params *s));
                    154: double speed_mpn_kara_sqr_n _PROTO ((struct speed_params *s));
                    155: double speed_mpn_lshift _PROTO ((struct speed_params *s));
                    156: double speed_mpn_mod_1 _PROTO ((struct speed_params *s));
                    157: double speed_mpn_mod_1c _PROTO ((struct speed_params *s));
                    158: double speed_mpn_mul_1 _PROTO ((struct speed_params *s));
                    159: double speed_mpn_mul_basecase _PROTO ((struct speed_params *s));
                    160: double speed_mpn_mul_fft _PROTO ((struct speed_params *s));
                    161: double speed_mpn_mul_fft_sqr _PROTO ((struct speed_params *s));
                    162: double speed_mpn_mul_fft_full _PROTO ((struct speed_params *s));
                    163: double speed_mpn_mul_fft_full_sqr _PROTO ((struct speed_params *s));
                    164: double speed_mpn_mul_n _PROTO ((struct speed_params *s));
                    165: double speed_mpn_mul_n_sqr _PROTO ((struct speed_params *s));
                    166: double speed_mpn_mul_n_toom3 _PROTO ((struct speed_params *s));
                    167: double speed_mpn_nand_n _PROTO ((struct speed_params *s));
                    168: double speed_mpn_nior_n _PROTO ((struct speed_params *s));
                    169: double speed_mpn_popcount _PROTO ((struct speed_params *s));
                    170: double speed_mpn_rshift _PROTO ((struct speed_params *s));
                    171: double speed_mpn_sqr_basecase _PROTO ((struct speed_params *s));
                    172: double speed_mpn_sqr_n _PROTO ((struct speed_params *s));
                    173: double speed_mpn_sqr_toom3 _PROTO ((struct speed_params *s));
                    174: double speed_mpn_sub_n _PROTO ((struct speed_params *s));
                    175: double speed_mpn_submul_1 _PROTO ((struct speed_params *s));
                    176: double speed_mpn_toom3_mul_n _PROTO ((struct speed_params *s));
                    177: double speed_mpn_toom3_sqr_n _PROTO ((struct speed_params *s));
                    178: double speed_mpn_udiv_qrnnd _PROTO ((struct speed_params *s));
                    179: double speed_mpn_umul_ppmm _PROTO ((struct speed_params *s));
                    180: double speed_mpn_xnor_n _PROTO ((struct speed_params *s));
                    181: double speed_mpn_xor_n _PROTO ((struct speed_params *s));
                    182:
                    183: double speed_mpq_init_clear _PROTO ((struct speed_params *s));
                    184:
                    185: double speed_mpz_add _PROTO ((struct speed_params *s));
                    186: double speed_mpz_bin_uiui _PROTO ((struct speed_params *s));
                    187: double speed_mpz_fac_ui _PROTO ((struct speed_params *s));
                    188: double speed_mpz_fib_ui _PROTO ((struct speed_params *s));
                    189: double speed_mpz_init_clear _PROTO ((struct speed_params *s));
                    190: double speed_mpz_init_realloc_clear _PROTO ((struct speed_params *s));
                    191: double speed_mpz_powm _PROTO ((struct speed_params *s));
                    192:
                    193: double speed_noop _PROTO ((struct speed_params *s));
                    194: double speed_noop_wxs _PROTO ((struct speed_params *s));
                    195: double speed_noop_wxys _PROTO ((struct speed_params *s));
                    196:
                    197: double speed_udiv_qrnnd _PROTO ((struct speed_params *s));
                    198: double speed_udiv_qrnnd_preinv _PROTO ((struct speed_params *s));
                    199: double speed_udiv_qrnnd_preinv2norm _PROTO ((struct speed_params *s));
                    200: double speed_umul_ppmm _PROTO ((struct speed_params *s));
                    201:
                    202:
                    203: /* Prototypes for other routines */
                    204:
                    205: /* low 32-bits in p[0], high 32-bits in p[1] */
                    206: void speed_cyclecounter _PROTO ((unsigned p[2]));
                    207:
                    208: void pentium_wbinvd _PROTO ((void));
                    209:
                    210: void noop _PROTO ((void));
                    211: void noop_1 _PROTO ((mp_limb_t n));
                    212: void noop_wxs _PROTO ((mp_ptr wp, mp_srcptr xp, mp_size_t size));
                    213: void noop_wxys _PROTO ((mp_ptr wp, mp_srcptr xp, mp_srcptr yp,
                    214:                         mp_size_t size));
                    215: void mpn_cache_fill _PROTO ((mp_srcptr ptr, mp_size_t size));
                    216: void mpn_cache_fill_dummy _PROTO ((mp_limb_t n));
                    217: mp_ptr speed_tmp_alloc_adjust _PROTO ((void *ptr, mp_size_t align));
                    218: void *_mp_allocate_or_reallocate _PROTO ((void *ptr,
                    219:                                           size_t oldsize, size_t newsize));
                    220: void *align_pointer _PROTO ((void *p, size_t align));
                    221: void *_mp_allocate_func_aligned _PROTO ((size_t bytes, size_t align));
                    222: void speed_cache_fill _PROTO ((struct speed_params *s));
                    223: void speed_operand_src _PROTO ((struct speed_params *s,
                    224:                                 mp_ptr ptr, mp_size_t size));
                    225: void speed_operand_dst _PROTO ((struct speed_params *s,
                    226:                                 mp_ptr ptr, mp_size_t size));
                    227: void mpz_set_n _PROTO ((mpz_ptr z, mp_srcptr p, mp_size_t size));
                    228:
                    229: extern int  speed_option_addrs;
                    230: void speed_option_set _PROTO((const char *s));
                    231:
                    232:
                    233: #define SPEED_RESTRICT_COND(cond)   if (!(cond)) return -1.0;
                    234:
                    235: /* For mpn_copy or similar. */
                    236: #define SPEED_ROUTINE_MPN_COPY_CALL(call)               \
                    237:   {                                                     \
                    238:     mp_ptr    wp;                                       \
                    239:     unsigned  i;                                        \
                    240:     double    t;                                        \
                    241:     TMP_DECL (marker);                                  \
                    242:                                                         \
                    243:     SPEED_RESTRICT_COND (s->size >= 0);                 \
                    244:                                                         \
                    245:     TMP_MARK (marker);                                  \
                    246:     wp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);  \
                    247:                                                         \
                    248:     speed_operand_src (s, s->xp, s->size);              \
                    249:     speed_operand_dst (s, wp, s->size);                 \
                    250:     speed_cache_fill (s);                               \
                    251:                                                         \
                    252:     speed_starttime ();                                 \
                    253:     i = s->reps;                                        \
                    254:     do                                                  \
                    255:       call;                                             \
                    256:     while (--i != 0);                                   \
                    257:     t = speed_endtime ();                               \
                    258:                                                         \
                    259:     TMP_FREE (marker);                                  \
                    260:     return t;                                           \
                    261:   }
                    262:
                    263: #define SPEED_ROUTINE_MPN_COPY(function) \
                    264:   SPEED_ROUTINE_MPN_COPY_CALL(function (wp, s->xp, s->size))
                    265: #define SPEED_ROUTINE_MPN_COPYC(function) \
                    266:   SPEED_ROUTINE_MPN_COPY_CALL(function (wp, s->xp, s->size, 0))
                    267:
                    268:
                    269: /* For mpn_add_n, mpn_sub_n, or similar. */
                    270: #define SPEED_ROUTINE_MPN_BINARY_N_CALL(call)           \
                    271:   {                                                     \
                    272:     mp_ptr    wp;                                       \
                    273:     unsigned  i;                                        \
                    274:     double    t;                                        \
                    275:     TMP_DECL (marker);                                  \
                    276:                                                         \
                    277:     SPEED_RESTRICT_COND (s->size >= 1);                 \
                    278:                                                         \
                    279:     TMP_MARK (marker);                                  \
                    280:     wp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);  \
                    281:                                                         \
                    282:     speed_operand_src (s, s->xp, s->size);              \
                    283:     speed_operand_src (s, s->yp, s->size);              \
                    284:     speed_operand_dst (s, wp, s->size);                 \
                    285:     speed_cache_fill (s);                               \
                    286:                                                         \
                    287:     speed_starttime ();                                 \
                    288:     i = s->reps;                                        \
                    289:     do                                                  \
                    290:       call;                                             \
                    291:     while (--i != 0);                                   \
                    292:     t = speed_endtime ();                               \
                    293:                                                         \
                    294:     TMP_FREE (marker);                                  \
                    295:     return t;                                           \
                    296:   }
                    297:
                    298: #define SPEED_ROUTINE_MPN_BINARY_N(function) \
                    299:    SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, s->xp, s->yp, s->size))
                    300:
                    301: #define SPEED_ROUTINE_MPN_BINARY_NC(function) \
                    302:    SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, s->xp, s->yp, s->size, 0))
                    303:
                    304: #define SPEED_ROUTINE_MPN_BINARY_N_SELF(function) \
                    305:    SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, s->xp, s->xp, s->size))
                    306:
                    307: #define SPEED_ROUTINE_MPN_BINARY_N_INPLACE(function) \
                    308:    SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, wp, s->xp, s->size))
                    309:
                    310:
                    311: /* For mpn_lshift, mpn_rshift, mpn_mul_1, with r, or similar. */
                    312: #define SPEED_ROUTINE_MPN_UNARY_1_CALL(call)            \
                    313:   {                                                     \
                    314:     mp_ptr    wp;                                       \
                    315:     unsigned  i;                                        \
                    316:     double    t;                                        \
                    317:     TMP_DECL (marker);                                  \
                    318:                                                         \
                    319:     SPEED_RESTRICT_COND (s->size >= 1);                 \
                    320:                                                         \
                    321:     TMP_MARK (marker);                                  \
                    322:     wp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);  \
                    323:                                                         \
                    324:     speed_operand_src (s, s->xp, s->size);              \
                    325:     speed_operand_dst (s, wp, s->size);                 \
                    326:     speed_cache_fill (s);                               \
                    327:                                                         \
                    328:     speed_starttime ();                                 \
                    329:     i = s->reps;                                        \
                    330:     do                                                  \
                    331:       call;                                             \
                    332:     while (--i != 0);                                   \
                    333:     t = speed_endtime ();                               \
                    334:                                                         \
                    335:     TMP_FREE (marker);                                  \
                    336:     return t;                                           \
                    337:   }
                    338:
                    339: #define SPEED_ROUTINE_MPN_UNARY_1(function) \
                    340:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r))
                    341:
                    342: #define SPEED_ROUTINE_MPN_UNARY_1C(function) \
                    343:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r, 0))
                    344:
                    345: #define SPEED_ROUTINE_MPN_DIVREM_1(function) \
                    346:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, 0, s->xp, s->size, s->r))
                    347:
                    348: #define SPEED_ROUTINE_MPN_DIVREM_1C(function) \
                    349:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, 0, s->xp, s->size, s->r, 0))
                    350:
                    351: #define SPEED_ROUTINE_MPN_DIVREM_1F(function) \
                    352:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->size, s->xp, 0, s->r))
                    353:
                    354: #define SPEED_ROUTINE_MPN_DIVREM_1CF(function) \
                    355:   SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->size, s->xp, 0, s->r, 0))
                    356:
                    357:
                    358: /* For mpn_mul_basecase, xsize=r, ysize=s->size. */
                    359: #define SPEED_ROUTINE_MPN_MUL_BASECASE(function)                \
                    360:   {                                                             \
                    361:     mp_ptr    wp;                                               \
                    362:     mp_size_t  size1;                                           \
                    363:     unsigned  i;                                                \
                    364:     double    t;                                                \
                    365:     TMP_DECL (marker);                                          \
                    366:                                                                 \
                    367:     size1 = (s->r == 0 ? s->size : s->r);                       \
                    368:                                                                 \
                    369:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    370:     SPEED_RESTRICT_COND (size1 >= s->size);                     \
                    371:                                                                 \
                    372:     TMP_MARK (marker);                                          \
                    373:     wp = SPEED_TMP_ALLOC_LIMBS (size1 + s->size, s->align_wp);  \
                    374:                                                                 \
                    375:     speed_operand_src (s, s->xp, size1);                        \
                    376:     speed_operand_src (s, s->yp, s->size);                      \
                    377:     speed_operand_dst (s, wp, size1 + s->size);                 \
                    378:     speed_cache_fill (s);                                       \
                    379:                                                                 \
                    380:     speed_starttime ();                                         \
                    381:     i = s->reps;                                                \
                    382:     do                                                          \
                    383:       function (wp, s->xp, size1, s->yp, s->size);              \
                    384:     while (--i != 0);                                           \
                    385:     t = speed_endtime ();                                       \
                    386:                                                                 \
                    387:     TMP_FREE (marker);                                          \
                    388:     return t;                                                   \
                    389:   }
                    390:
                    391:
                    392: #define SPEED_ROUTINE_MPN_MUL_N_CALL(call)                      \
                    393:   {                                                             \
                    394:     mp_ptr    wp;                                               \
                    395:     unsigned  i;                                                \
                    396:     double    t;                                                \
                    397:     TMP_DECL (marker);                                          \
                    398:                                                                 \
                    399:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    400:                                                                 \
                    401:     TMP_MARK (marker);                                          \
                    402:     wp = SPEED_TMP_ALLOC_LIMBS (2*s->size, s->align_wp);        \
                    403:                                                                 \
                    404:     speed_operand_src (s, s->xp, s->size);                      \
                    405:     speed_operand_src (s, s->yp, s->size);                      \
                    406:     speed_operand_dst (s, wp, 2*s->size);                       \
                    407:     speed_cache_fill (s);                                       \
                    408:                                                                 \
                    409:     speed_starttime ();                                         \
                    410:     i = s->reps;                                                \
                    411:     do                                                          \
                    412:       call;                                                     \
                    413:     while (--i != 0);                                           \
                    414:     t = speed_endtime ();                                       \
                    415:                                                                 \
                    416:     TMP_FREE (marker);                                          \
                    417:     return t;                                                   \
                    418:   }
                    419:
                    420: #define SPEED_ROUTINE_MPN_MUL_N(function) \
                    421:   SPEED_ROUTINE_MPN_MUL_N_CALL (function (wp, s->xp, s->yp, s->size));
                    422:
                    423:
                    424: #define SPEED_ROUTINE_MPN_MUL_N_TSPACE(call, tsize)             \
                    425:   {                                                             \
                    426:     mp_ptr    wp, tspace;                                       \
                    427:     unsigned  i;                                                \
                    428:     double    t;                                                \
                    429:     TMP_DECL (marker);                                          \
                    430:                                                                 \
                    431:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    432:                                                                 \
                    433:     TMP_MARK (marker);                                          \
                    434:     wp = SPEED_TMP_ALLOC_LIMBS (2*s->size, s->align_wp);        \
                    435:     tspace = SPEED_TMP_ALLOC_LIMBS (tsize, s->align_wp2);       \
                    436:                                                                 \
                    437:     speed_operand_src (s, s->xp, s->size);                      \
                    438:     speed_operand_src (s, s->yp, s->size);                      \
                    439:     speed_operand_dst (s, wp, 2*s->size);                       \
                    440:     speed_operand_dst (s, tspace, tsize);                       \
                    441:     speed_cache_fill (s);                                       \
                    442:                                                                 \
                    443:     speed_starttime ();                                         \
                    444:     i = s->reps;                                                \
                    445:     do                                                          \
                    446:       call;                                                     \
                    447:     while (--i != 0);                                           \
                    448:     t = speed_endtime ();                                       \
                    449:                                                                 \
                    450:     TMP_FREE (marker);                                          \
                    451:     return t;                                                   \
                    452:   }
                    453:
                    454: /* FIXME: size restrictions */
                    455: #define SPEED_ROUTINE_MPN_KARA_MUL_N(function)          \
                    456:   SPEED_ROUTINE_MPN_MUL_N_TSPACE                        \
                    457:     (function (wp, s->xp, s->xp, s->size, tspace),      \
                    458:      MPN_KARA_MUL_N_TSIZE (s->size))
                    459:
                    460: /* FIXME: size restrictions */
                    461: #define SPEED_ROUTINE_MPN_TOOM3_MUL_N(function)         \
                    462:   SPEED_ROUTINE_MPN_MUL_N_TSPACE                        \
                    463:     (function (wp, s->xp, s->yp, s->size, tspace),      \
                    464:      MPN_TOOM3_MUL_N_TSIZE (s->size))
                    465:
                    466:
                    467: #define SPEED_ROUTINE_MPN_SQR_CALL(call)                        \
                    468:   {                                                             \
                    469:     mp_ptr    wp;                                               \
                    470:     unsigned  i;                                                \
                    471:     double    t;                                                \
                    472:     TMP_DECL (marker);                                          \
                    473:                                                                 \
                    474:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    475:                                                                 \
                    476:     TMP_MARK (marker);                                          \
                    477:     wp = SPEED_TMP_ALLOC_LIMBS (2*s->size, s->align_wp);        \
                    478:                                                                 \
                    479:     speed_operand_src (s, s->xp, s->size);                      \
                    480:     speed_operand_dst (s, wp, 2*s->size);                       \
                    481:     speed_cache_fill (s);                                       \
                    482:                                                                 \
                    483:     speed_starttime ();                                         \
                    484:     i = s->reps;                                                \
                    485:     do                                                          \
                    486:       call;                                                     \
                    487:     while (--i != 0);                                           \
                    488:     t = speed_endtime ();                                       \
                    489:                                                                 \
                    490:     TMP_FREE (marker);                                          \
                    491:     return t;                                                   \
                    492:   }
                    493:
                    494: #define SPEED_ROUTINE_MPN_SQR(function) \
                    495:   SPEED_ROUTINE_MPN_SQR_CALL (function (wp, s->xp, s->size))
                    496:
                    497:
                    498: #define SPEED_ROUTINE_MPN_SQR_TSPACE(call, tsize)               \
                    499:   {                                                             \
                    500:     mp_ptr    wp, tspace;                                       \
                    501:     unsigned  i;                                                \
                    502:     double    t;                                                \
                    503:     TMP_DECL (marker);                                          \
                    504:                                                                 \
                    505:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    506:                                                                 \
                    507:     TMP_MARK (marker);                                          \
                    508:     wp = SPEED_TMP_ALLOC_LIMBS (2*s->size, s->align_wp);        \
                    509:     tspace = SPEED_TMP_ALLOC_LIMBS (tsize, s->align_wp2);       \
                    510:                                                                 \
                    511:     speed_operand_src (s, s->xp, s->size);                      \
                    512:     speed_operand_dst (s, wp, 2*s->size);                       \
                    513:     speed_operand_dst (s, tspace, tsize);                       \
                    514:     speed_cache_fill (s);                                       \
                    515:                                                                 \
                    516:     speed_starttime ();                                         \
                    517:     i = s->reps;                                                \
                    518:     do                                                          \
                    519:       call;                                                     \
                    520:     while (--i != 0);                                           \
                    521:     t = speed_endtime ();                                       \
                    522:                                                                 \
                    523:     TMP_FREE (marker);                                          \
                    524:     return t;                                                   \
                    525:   }
                    526:
                    527: /* FIXME: size restrictions */
                    528: #define SPEED_ROUTINE_MPN_KARA_SQR_N(function)                          \
                    529:   SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace),  \
                    530:                                 MPN_KARA_SQR_N_TSIZE (s->size))
                    531:
                    532: /* FIXME: size restrictions */
                    533: #define SPEED_ROUTINE_MPN_TOOM3_SQR_N(function)                         \
                    534:   SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace),  \
                    535:                                 MPN_TOOM3_SQR_N_TSIZE (s->size))
                    536:
                    537:
                    538: #define SPEED_ROUTINE_MPN_MOD_CALL(call)        \
                    539:   {                                             \
                    540:     unsigned  i;                                \
                    541:                                                 \
                    542:     SPEED_RESTRICT_COND (s->size >= 0);         \
                    543:                                                 \
                    544:     speed_operand_src (s, s->xp, s->size);      \
                    545:     speed_cache_fill (s);                       \
                    546:                                                 \
                    547:     speed_starttime ();                         \
                    548:     i = s->reps;                                \
                    549:     do                                          \
                    550:       call;                                     \
                    551:     while (--i != 0);                           \
                    552:     return speed_endtime ();                    \
                    553:   }
                    554:
                    555: #define SPEED_ROUTINE_MPN_MOD_1(function)  \
                    556:    SPEED_ROUTINE_MPN_MOD_CALL ((*function) (s->xp, s->size, s->r))
                    557:
                    558: #define SPEED_ROUTINE_MPN_MOD_1C(function) \
                    559:    SPEED_ROUTINE_MPN_MOD_CALL ((*function) (s->xp, s->size, s->r, 0))
                    560:
                    561:
                    562: /* A division of 2*s->size by s->size limbs */
                    563:
                    564: #define SPEED_ROUTINE_MPN_BZ_DIVREM_CALL(call)                  \
                    565:   {                                                             \
                    566:     unsigned   i;                                               \
                    567:     mp_ptr     a, d, q, r;                                      \
                    568:     double    t;                                                \
                    569:     TMP_DECL (marker);                                          \
                    570:                                                                 \
                    571:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    572:                                                                 \
                    573:     TMP_MARK (marker);                                          \
                    574:     a = SPEED_TMP_ALLOC_LIMBS (2*s->size, s->align_xp);         \
                    575:     d = SPEED_TMP_ALLOC_LIMBS (s->size,   s->align_yp);         \
                    576:     q = SPEED_TMP_ALLOC_LIMBS (s->size+1, s->align_wp);         \
                    577:     r = SPEED_TMP_ALLOC_LIMBS (s->size,   s->align_wp2);        \
                    578:                                                                 \
                    579:     MPN_COPY (a, s->xp, s->size);                               \
                    580:     MPN_COPY (a+s->size, s->xp, s->size);                       \
                    581:                                                                 \
                    582:     MPN_COPY (d, s->yp, s->size);                               \
                    583:                                                                 \
                    584:     /* normalize the data */                                    \
                    585:     d[s->size-1] |= MP_LIMB_T_HIGHBIT;                          \
                    586:     a[2*s->size-1] = d[s->size-1] - 1;                          \
                    587:                                                                 \
                    588:     speed_operand_src (s, a, 2*s->size);                        \
                    589:     speed_operand_src (s, d, s->size);                          \
                    590:     speed_operand_dst (s, q, s->size+1);                        \
                    591:     speed_operand_dst (s, r, s->size);                          \
                    592:     speed_cache_fill (s);                                       \
                    593:                                                                 \
                    594:     speed_starttime ();                                         \
                    595:     i = s->reps;                                                \
                    596:     do                                                          \
                    597:       call;                                                     \
                    598:     while (--i != 0);                                           \
                    599:     t = speed_endtime ();                                       \
                    600:                                                                 \
                    601:     TMP_FREE (marker);                                          \
                    602:     return t;                                                   \
                    603:   }
                    604:
                    605: #define SPEED_ROUTINE_MPN_BZ_DIVREM_N(function) \
                    606:   SPEED_ROUTINE_MPN_BZ_DIVREM_CALL((*function) (q, a, d, s->size))
                    607:
                    608: #define SPEED_ROUTINE_MPN_BZ_DIVREM_SB(function)        \
                    609:   SPEED_ROUTINE_MPN_BZ_DIVREM_CALL                      \
                    610:     ((*function) (q, a, 2*s->size, d, s->size))
                    611:
                    612: #define SPEED_ROUTINE_MPN_BZ_TDIV_QR(function)          \
                    613:   SPEED_ROUTINE_MPN_BZ_DIVREM_CALL                      \
                    614:     ((*function) (q, r, 0, a, 2*s->size, d, s->size))
                    615:
                    616:
                    617: #define SPEED_ROUTINE_MPN_POPCOUNT(function)    \
                    618:   {                                             \
                    619:     unsigned  i;                                \
                    620:                                                 \
                    621:     SPEED_RESTRICT_COND (s->size >= 1);         \
                    622:                                                 \
                    623:     speed_operand_src (s, s->xp, s->size);      \
                    624:     speed_cache_fill (s);                       \
                    625:                                                 \
                    626:     speed_starttime ();                         \
                    627:     i = s->reps;                                \
                    628:     do                                          \
                    629:       function (s->xp, s->size);                \
                    630:     while (--i != 0);                           \
                    631:     return speed_endtime ();                    \
                    632:   }
                    633:
                    634: #define SPEED_ROUTINE_MPN_HAMDIST(function)     \
                    635:   {                                             \
                    636:     unsigned  i;                                \
                    637:                                                 \
                    638:     SPEED_RESTRICT_COND (s->size >= 1);         \
                    639:                                                 \
                    640:     speed_operand_src (s, s->xp, s->size);      \
                    641:     speed_operand_src (s, s->yp, s->size);      \
                    642:     speed_cache_fill (s);                       \
                    643:                                                 \
                    644:     speed_starttime ();                         \
                    645:     i = s->reps;                                \
                    646:     do                                          \
                    647:       function (s->xp, s->yp, s->size);         \
                    648:     while (--i != 0);                           \
                    649:     return speed_endtime ();                    \
                    650:   }
                    651:
                    652:
                    653: /* For mpz_fib_ui, mpz_fac_ui, etc */
                    654:
                    655: #define SPEED_ROUTINE_MPZ_UI(function)  \
                    656:   {                                     \
                    657:     mpz_t     z;                        \
                    658:     unsigned  i;                        \
                    659:     double    t;                        \
                    660:                                         \
                    661:     SPEED_RESTRICT_COND (s->size >= 0); \
                    662:                                         \
                    663:     mpz_init (z);                       \
                    664:                                         \
                    665:     speed_starttime ();                 \
                    666:     i = s->reps;                        \
                    667:     do                                  \
                    668:       function (z, s->size);            \
                    669:     while (--i != 0);                   \
                    670:     t = speed_endtime ();               \
                    671:                                         \
                    672:     mpz_clear (z);                      \
                    673:     return t;                           \
                    674:   }
                    675:
                    676:
                    677: /* Calculate 2^(m-1) mod m for random odd m of s->size limbs.  Having m odd
                    678:    allows redc to be used.  Actually the exponent (m-1) is cut down to at
                    679:    most 6 limbs so the calculation doesn't take too long.  */
                    680: #define SPEED_ROUTINE_MPZ_POWM(function)        \
                    681:   {                                             \
                    682:     mpz_t     r, b, e, m;                       \
                    683:     unsigned  i;                                \
                    684:     double    t;                                \
                    685:                                                 \
                    686:     SPEED_RESTRICT_COND (s->size >= 1);         \
                    687:                                                 \
                    688:     mpz_init (r);                               \
                    689:     mpz_init_set_ui (b, 2);                     \
                    690:                                                 \
                    691:     /* force m to odd */                        \
                    692:     mpz_init (m);                               \
                    693:     mpz_set_n (m, s->xp, s->size);              \
                    694:     PTR(m)[0] |= 1;                             \
                    695:                                                 \
                    696:     mpz_init_set (e, m);                        \
                    697:     mpz_sub_ui (e, e, 1);                       \
                    698:     SIZ(e) = MIN (SIZ(e), 6);                   \
                    699:                                                 \
                    700:     speed_starttime ();                         \
                    701:     i = s->reps;                                \
                    702:     do                                          \
                    703:       function (r, b, e, m);                    \
                    704:     while (--i != 0);                           \
                    705:     t = speed_endtime ();                       \
                    706:                                                 \
                    707:     mpz_clear (r);                              \
                    708:     mpz_clear (b);                              \
                    709:     mpz_clear (e);                              \
                    710:     mpz_clear (m);                              \
                    711:     return t;                                   \
                    712:   }
                    713:
                    714:
                    715: #define SPEED_ROUTINE_MPN_ADDSUB_CALL(call)                               \
                    716:   {                                                                       \
                    717:     mp_ptr    wp, wp2, xp, yp;                                            \
                    718:     unsigned  i;                                                          \
                    719:     double    t;                                                          \
                    720:     TMP_DECL (marker);                                                    \
                    721:                                                                           \
                    722:     SPEED_RESTRICT_COND (s->size >= 0);                                   \
                    723:                                                                           \
                    724:     TMP_MARK (marker);                                                    \
                    725:     wp  = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);                   \
                    726:     wp2 = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp2);                  \
                    727:     xp = s->xp;                                                           \
                    728:     yp = s->yp;                                                           \
                    729:                                                                           \
                    730:     switch (s->r) {                                                       \
                    731:     case 0:                           break;                              \
                    732:     case 1: xp =    wp;               break;                              \
                    733:     case 2:              yp =    wp2; break;                              \
                    734:     case 3: xp =    wp;  yp =    wp2; break;                              \
                    735:     case 4: xp =    wp2; yp =    wp;  break;                              \
                    736:     default:                                                              \
                    737:       fprintf (stderr, "Unrecognised r=%ld in addsub measuring\n", s->r); \
                    738:       abort ();                                                           \
                    739:     }                                                                     \
                    740:     if (xp != s->xp) MPN_COPY (xp, s->xp, s->size);                       \
                    741:     if (yp != s->yp) MPN_COPY (yp, s->yp, s->size);                       \
                    742:                                                                           \
                    743:     speed_operand_src (s, xp, s->size);                                   \
                    744:     speed_operand_src (s, yp, s->size);                                   \
                    745:     speed_operand_dst (s, wp, s->size);                                   \
                    746:     speed_operand_dst (s, wp2, s->size);                                  \
                    747:     speed_cache_fill (s);                                                 \
                    748:                                                                           \
                    749:     speed_starttime ();                                                   \
                    750:     i = s->reps;                                                          \
                    751:     do                                                                    \
                    752:       call;                                                               \
                    753:     while (--i != 0);                                                     \
                    754:     t = speed_endtime ();                                                 \
                    755:                                                                           \
                    756:     TMP_FREE (marker);                                                    \
                    757:     return t;                                                             \
                    758:   }
                    759:
                    760: #define SPEED_ROUTINE_MPN_ADDSUB_N(function)    \
                    761:   SPEED_ROUTINE_MPN_ADDSUB_CALL                 \
                    762:     (function (wp, wp2, xp, yp, s->size));
                    763:
                    764: #define SPEED_ROUTINE_MPN_ADDSUB_NC(function)   \
                    765:   SPEED_ROUTINE_MPN_ADDSUB_CALL                 \
                    766:     (function (wp, wp2, xp, yp, s->size, 0));
                    767:
                    768:
                    769: #define SPEED_ROUTINE_MPN_GCD_1xN(function)     \
                    770:   {                                             \
                    771:     unsigned  i;                                \
                    772:     double    t;                                \
                    773:     TMP_DECL (marker);                          \
                    774:                                                 \
                    775:     SPEED_RESTRICT_COND (s->size >= 1);         \
                    776:     SPEED_RESTRICT_COND (s->r != 0);            \
                    777:                                                 \
                    778:     TMP_MARK (marker);                          \
                    779:                                                 \
                    780:     speed_operand_src (s, s->xp, s->size);      \
                    781:     speed_cache_fill (s);                       \
                    782:                                                 \
                    783:     speed_starttime ();                         \
                    784:     i = s->reps;                                \
                    785:     do                                          \
                    786:       function (s->xp, s->size, s->r);          \
                    787:     while (--i != 0);                           \
                    788:     t = speed_endtime ();                       \
                    789:                                                 \
                    790:     TMP_FREE (marker);                          \
                    791:     return t;                                   \
                    792:   }
                    793:
                    794:
                    795: /* SPEED_BLOCK_SIZE many one GCDs of s->size bits each. */
                    796:
                    797: #define SPEED_ROUTINE_MPN_GCD_1_CALL(setup, call)               \
                    798:   {                                                             \
                    799:     unsigned  i, j;                                             \
                    800:     mp_ptr    px, py;                                           \
                    801:     mp_limb_t x_mask, y_mask;                                   \
                    802:     double    t;                                                \
                    803:     TMP_DECL (marker);                                          \
                    804:                                                                 \
                    805:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    806:     SPEED_RESTRICT_COND (s->size <= mp_bits_per_limb);          \
                    807:                                                                 \
                    808:     TMP_MARK (marker);                                          \
                    809:     px = SPEED_TMP_ALLOC_LIMBS (SPEED_BLOCK_SIZE, s->align_xp); \
                    810:     py = SPEED_TMP_ALLOC_LIMBS (SPEED_BLOCK_SIZE, s->align_yp); \
                    811:     MPN_COPY (px, s->xp_block, SPEED_BLOCK_SIZE);               \
                    812:     MPN_COPY (py, s->yp_block, SPEED_BLOCK_SIZE);               \
                    813:                                                                 \
                    814:     x_mask = MP_LIMB_T_LOWBITMASK (s->size);                    \
                    815:     y_mask = MP_LIMB_T_LOWBITMASK (s->r != 0 ? s->r : s->size); \
                    816:     for (i = 0; i < SPEED_BLOCK_SIZE; i++)                      \
                    817:       {                                                         \
                    818:         px[i] &= x_mask; px[i] += (px[i] == 0);                 \
                    819:         py[i] &= y_mask; py[i] += (py[i] == 0);                 \
                    820:         setup;                                                  \
                    821:       }                                                         \
                    822:                                                                 \
                    823:     speed_operand_src (s, px, SPEED_BLOCK_SIZE);                \
                    824:     speed_operand_src (s, py, SPEED_BLOCK_SIZE);                \
                    825:     speed_cache_fill (s);                                       \
                    826:                                                                 \
                    827:     speed_starttime ();                                         \
                    828:     i = s->reps;                                                \
                    829:     do                                                          \
                    830:       {                                                         \
                    831:         j = SPEED_BLOCK_SIZE;                                   \
                    832:         do                                                      \
                    833:           {                                                     \
                    834:             call;                                               \
                    835:           }                                                     \
                    836:         while (--j != 0);                                       \
                    837:       }                                                         \
                    838:     while (--i != 0);                                           \
                    839:     t = speed_endtime ();                                       \
                    840:                                                                 \
                    841:     TMP_FREE (marker);                                          \
                    842:                                                                 \
                    843:     s->time_divisor = SPEED_BLOCK_SIZE;                         \
                    844:     return t;                                                   \
                    845:   }
                    846:
                    847: #define SPEED_ROUTINE_MPN_GCD_1(function) \
                    848:   SPEED_ROUTINE_MPN_GCD_1_CALL( , function (&px[j-1], 1, py[j-1]))
                    849:
                    850: #define SPEED_ROUTINE_MPN_JACBASE(function)     \
                    851:   SPEED_ROUTINE_MPN_GCD_1_CALL                  \
                    852:     ({                                          \
                    853:        px[i] %= py[i];                          \
                    854:        px[i] |= 1;                              \
                    855:        py[i] |= 1;                              \
                    856:        if (py[i]==1) py[i]=3;                   \
                    857:      },                                         \
                    858:      function (px[j-1], py[j-1], 0))
                    859:
                    860:
                    861: /* Run some GCDs of s->size limbs each.  The number of different data values
                    862:    is decreased as s->size**2, since GCD is a quadratic algorithm.
                    863:    SPEED_ROUTINE_MPN_GCD runs more times than SPEED_ROUTINE_MPN_GCDEXT
                    864:    though, because the plain gcd is about twice as fast as gcdext.  */
                    865:
                    866: #define SPEED_ROUTINE_MPN_GCD_CALL(datafactor, call)            \
                    867:   {                                                             \
                    868:     unsigned  i;                                                \
                    869:     mp_size_t j, pieces, psize;                                 \
                    870:     mp_ptr    wp, wp2, xtmp, ytmp, px, py;                      \
                    871:     double    t;                                                \
                    872:     TMP_DECL (marker);                                          \
                    873:                                                                 \
                    874:     SPEED_RESTRICT_COND (s->size >= 1);                         \
                    875:                                                                 \
                    876:     TMP_MARK (marker);                                          \
                    877:     xtmp = SPEED_TMP_ALLOC_LIMBS (s->size+1, s->align_xp);      \
                    878:     ytmp = SPEED_TMP_ALLOC_LIMBS (s->size+1, s->align_yp);      \
                    879:     wp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);          \
                    880:     wp2 = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp2);        \
                    881:                                                                 \
                    882:     pieces = SPEED_BLOCK_SIZE * datafactor / s->size / s->size; \
                    883:     pieces = MAX (pieces, 1);                                   \
                    884:     pieces = MIN (pieces, SPEED_BLOCK_SIZE / s->size);          \
                    885:                                                                 \
                    886:     psize = pieces * s->size;                                   \
                    887:     px = TMP_ALLOC_LIMBS (psize);                               \
                    888:     py = TMP_ALLOC_LIMBS (psize);                               \
                    889:     MPN_COPY (px, pieces==1 ? s->xp : s->xp_block, psize);      \
                    890:     MPN_COPY (py, pieces==1 ? s->yp : s->yp_block, psize);      \
                    891:                                                                 \
                    892:     /* y must be odd, x must have at least as many bits as y */ \
                    893:     for (j = 0; j < pieces; j++)                                \
                    894:       {                                                         \
                    895:         mp_ptr  x = px+j*s->size;                               \
                    896:         mp_ptr  y = py+j*s->size;                               \
                    897:         y[0] |= 1;                                              \
                    898:         if (x[s->size-1] == 0) x[s->size-1] = 1;                \
                    899:         if (y[s->size-1] == 0) y[s->size-1] = 1;                \
                    900:         x[s->size-1] = MAX (x[s->size-1], y[s->size-1]);        \
                    901:       }                                                         \
                    902:                                                                 \
                    903:     speed_operand_src (s, px, psize);                           \
                    904:     speed_operand_src (s, py, psize);                           \
                    905:     speed_operand_dst (s, xtmp, s->size);                       \
                    906:     speed_operand_dst (s, ytmp, s->size);                       \
                    907:     speed_operand_dst (s, wp, s->size);                         \
                    908:     speed_cache_fill (s);                                       \
                    909:                                                                 \
                    910:     speed_starttime ();                                         \
                    911:     i = s->reps;                                                \
                    912:     do                                                          \
                    913:       {                                                         \
                    914:         j = pieces;                                             \
                    915:         do                                                      \
                    916:           {                                                     \
                    917:             MPN_COPY (xtmp, px+(j-1)*s->size, s->size);         \
                    918:             MPN_COPY (ytmp, py+(j-1)*s->size, s->size);         \
                    919:             call;                                               \
                    920:           }                                                     \
                    921:         while (--j != 0);                                       \
                    922:       }                                                         \
                    923:     while (--i != 0);                                           \
                    924:     t = speed_endtime ();                                       \
                    925:                                                                 \
                    926:     TMP_FREE (marker);                                          \
                    927:                                                                 \
                    928:     s->time_divisor = pieces;                                   \
                    929:     return t;                                                   \
                    930:   }
                    931:
                    932: #define SPEED_ROUTINE_MPN_GCD(function) \
                    933:   SPEED_ROUTINE_MPN_GCD_CALL (8, function (wp, xtmp, s->size, ytmp, s->size))
                    934:
                    935: #define SPEED_ROUTINE_MPN_GCDEXT(function)                               \
                    936:   SPEED_ROUTINE_MPN_GCD_CALL                                             \
                    937:     (4, { mp_size_t  wp2size;                                            \
                    938:           function (wp, wp2, &wp2size, xtmp, s->size, ytmp, s->size); })
                    939:
                    940:
                    941: #define SPEED_ROUTINE_MPN_DIVREM_2(function)            \
                    942:   {                                                     \
                    943:     mp_ptr    wp, xp;                                   \
                    944:     mp_limb_t yp[2];                                    \
                    945:     unsigned  i;                                        \
                    946:     double    t;                                        \
                    947:     TMP_DECL (marker);                                  \
                    948:                                                         \
                    949:     SPEED_RESTRICT_COND (s->size >= 1);                 \
                    950:                                                         \
                    951:     TMP_MARK (marker);                                  \
                    952:     xp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_xp);  \
                    953:     wp = SPEED_TMP_ALLOC_LIMBS (s->size, s->align_wp);  \
                    954:                                                         \
                    955:     /* source is destroyed */                           \
                    956:     MPN_COPY (xp, s->xp, s->size);                      \
                    957:                                                         \
                    958:     /* divisor must be normalized */                    \
                    959:     MPN_COPY (yp, s->yp_block, 2);                      \
                    960:     yp[1] |= MP_LIMB_T_HIGHBIT;                         \
                    961:                                                         \
                    962:     speed_operand_src (s, xp, s->size);                 \
                    963:     speed_operand_src (s, yp, 2);                       \
                    964:     speed_operand_dst (s, wp, s->size);                 \
                    965:     speed_cache_fill (s);                               \
                    966:                                                         \
                    967:     speed_starttime ();                                 \
                    968:     i = s->reps;                                        \
                    969:     do                                                  \
                    970:       function (wp, 0, xp, s->size, yp);                \
                    971:     while (--i != 0);                                   \
                    972:     t = speed_endtime ();                               \
                    973:                                                         \
                    974:     TMP_FREE (marker);                                  \
                    975:     return t;                                           \
                    976:   }
                    977:
                    978:
                    979: #define SPEED_ROUTINE_MODLIMB_INVERT(function)                  \
                    980:   {                                                             \
                    981:     unsigned   i, j;                                            \
                    982:     mp_ptr     xp;                                              \
                    983:     mp_limb_t  n = 1;                                           \
                    984:     double     t;                                               \
                    985:                                                                 \
                    986:     xp = s->xp_block-1;                                         \
                    987:                                                                 \
                    988:     speed_operand_src (s, s->xp_block, SPEED_BLOCK_SIZE);       \
                    989:     speed_cache_fill (s);                                       \
                    990:                                                                 \
                    991:     speed_starttime ();                                         \
                    992:     i = s->reps;                                                \
                    993:     do                                                          \
                    994:       {                                                         \
                    995:         j = SPEED_BLOCK_SIZE;                                   \
                    996:         do                                                      \
                    997:           {                                                     \
                    998:             /* randomized but successively dependent */         \
                    999:             n += (xp[j] << 1);                                  \
                   1000:                                                                 \
                   1001:             function (n, n);                                    \
                   1002:           }                                                     \
                   1003:         while (--j != 0);                                       \
                   1004:       }                                                         \
                   1005:     while (--i != 0);                                           \
                   1006:     t = speed_endtime ();                                       \
                   1007:                                                                 \
                   1008:     /* make sure the compiler won't optimize away n */          \
                   1009:     noop_1 (n);                                                 \
                   1010:                                                                 \
                   1011:     s->time_divisor = SPEED_BLOCK_SIZE;                         \
                   1012:     return t;                                                   \
                   1013:   }
                   1014:
                   1015: #endif

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