📄 try.c
字号:
{ MPN_COPY_DECR (rp, sp, size); }void__GMPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size){ __GMPN_COPY (rp, sp, size); }#ifdef __GMPN_COPY_INCRvoid__GMPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size){ __GMPN_COPY_INCR (rp, sp, size); }#endifvoidmpn_com_n_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size){ mpn_com_n (rp, sp, size); }voidmpn_and_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_and_n (rp, s1, s2, size); }voidmpn_andn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_andn_n (rp, s1, s2, size); }voidmpn_nand_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_nand_n (rp, s1, s2, size); }voidmpn_ior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_ior_n (rp, s1, s2, size); }voidmpn_iorn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_iorn_n (rp, s1, s2, size); }voidmpn_nior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_nior_n (rp, s1, s2, size); }voidmpn_xor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_xor_n (rp, s1, s2, size); }voidmpn_xnor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size){ mpn_xnor_n (rp, s1, s2, size); }mp_limb_tudiv_qrnnd_fun (mp_limb_t *remptr, mp_limb_t n1, mp_limb_t n0, mp_limb_t d){ mp_limb_t q; udiv_qrnnd (q, *remptr, n1, n0, d); return q;}mp_limb_tmpn_divexact_by3_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size){ return mpn_divexact_by3 (rp, sp, size);}mp_limb_tmpn_modexact_1_odd_fun (mp_srcptr ptr, mp_size_t size, mp_limb_t divisor){ return mpn_modexact_1_odd (ptr, size, divisor);}voidmpn_kara_mul_n_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size){ mp_ptr tspace; TMP_DECL (marker); TMP_MARK (marker); tspace = TMP_ALLOC_LIMBS (MPN_KARA_MUL_N_TSIZE (size)); mpn_kara_mul_n (dst, src1, src2, size, tspace);}voidmpn_kara_sqr_n_fun (mp_ptr dst, mp_srcptr src, mp_size_t size){ mp_ptr tspace; TMP_DECL (marker); TMP_MARK (marker); tspace = TMP_ALLOC_LIMBS (MPN_KARA_SQR_N_TSIZE (size)); mpn_kara_sqr_n (dst, src, size, tspace); TMP_FREE (marker);}voidmpn_toom3_mul_n_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size){ mp_ptr tspace; TMP_DECL (marker); TMP_MARK (marker); tspace = TMP_ALLOC_LIMBS (MPN_TOOM3_MUL_N_TSIZE (size)); mpn_toom3_mul_n (dst, src1, src2, size, tspace);}voidmpn_toom3_sqr_n_fun (mp_ptr dst, mp_srcptr src, mp_size_t size){ mp_ptr tspace; TMP_DECL (marker); TMP_MARK (marker); tspace = TMP_ALLOC_LIMBS (MPN_TOOM3_SQR_N_TSIZE (size)); mpn_toom3_sqr_n (dst, src, size, tspace); TMP_FREE (marker);}mp_limb_tumul_ppmm_fun (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2){ mp_limb_t high; umul_ppmm (high, *lowptr, m1, m2); return high;}mp_limb_tmpn_umul_ppmm_fun (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2){ mp_limb_t high; umul_ppmm (high, *lowptr, m1, m2); return high;}voidMPN_ZERO_fun (mp_ptr ptr, mp_size_t size){ MPN_ZERO (ptr, size); }struct choice_t { const char *name; tryfun_t function; int type; mp_size_t minsize;};#if HAVE_STRINGIZE#define TRY(fun) #fun, (tryfun_t) fun#define TRY_FUNFUN(fun) #fun, (tryfun_t) fun##_fun#else#define TRY(fun) "fun", (tryfun_t) fun#define TRY_FUNFUN(fun) "fun", (tryfun_t) fun/**/_fun#endifconst struct choice_t choice_array[] = { { TRY(mpn_add), TYPE_ADD }, { TRY(mpn_sub), TYPE_SUB }, { TRY(mpn_add_n), TYPE_ADD_N }, { TRY(mpn_sub_n), TYPE_SUB_N },#if HAVE_NATIVE_mpn_add_nc { TRY(mpn_add_nc), TYPE_ADD_NC },#endif#if HAVE_NATIVE_mpn_sub_nc { TRY(mpn_sub_nc), TYPE_SUB_NC },#endif { TRY(mpn_addmul_1), TYPE_ADDMUL_1 }, { TRY(mpn_submul_1), TYPE_SUBMUL_1 },#if HAVE_NATIVE_mpn_addmul_1c { TRY(mpn_addmul_1c), TYPE_ADDMUL_1C },#endif#if HAVE_NATIVE_mpn_submul_1c { TRY(mpn_submul_1c), TYPE_SUBMUL_1C },#endif { TRY_FUNFUN(mpn_com_n), TYPE_COM_N }, { TRY_FUNFUN(MPN_COPY), TYPE_COPY }, { TRY_FUNFUN(MPN_COPY_INCR), TYPE_COPYI }, { TRY_FUNFUN(MPN_COPY_DECR), TYPE_COPYD }, { TRY_FUNFUN(__GMPN_COPY), TYPE_COPY },#ifdef __GMPN_COPY_INCR { TRY_FUNFUN(__GMPN_COPY_INCR), TYPE_COPYI },#endif { TRY_FUNFUN(mpn_and_n), TYPE_AND_N }, { TRY_FUNFUN(mpn_andn_n), TYPE_ANDN_N }, { TRY_FUNFUN(mpn_nand_n), TYPE_NAND_N }, { TRY_FUNFUN(mpn_ior_n), TYPE_IOR_N }, { TRY_FUNFUN(mpn_iorn_n), TYPE_IORN_N }, { TRY_FUNFUN(mpn_nior_n), TYPE_NIOR_N }, { TRY_FUNFUN(mpn_xor_n), TYPE_XOR_N }, { TRY_FUNFUN(mpn_xnor_n), TYPE_XNOR_N }, { TRY(mpn_divrem_1), TYPE_DIVREM_1 },#if USE_PREINV_DIVREM_1 { TRY(mpn_preinv_divrem_1), TYPE_PREINV_DIVREM_1 },#endif { TRY(mpn_mod_1), TYPE_MOD_1 }, { TRY(mpn_preinv_mod_1), TYPE_PREINV_MOD_1 },#if HAVE_NATIVE_mpn_divrem_1c { TRY(mpn_divrem_1c), TYPE_DIVREM_1C },#endif#if HAVE_NATIVE_mpn_mod_1c { TRY(mpn_mod_1c), TYPE_MOD_1C },#endif { TRY(mpn_mod_34lsub1), TYPE_MOD_34LSUB1 }, { TRY_FUNFUN(udiv_qrnnd), TYPE_UDIV_QRNND, 2 }, { TRY(mpn_divexact_1), TYPE_DIVEXACT_1 }, { TRY_FUNFUN(mpn_divexact_by3), TYPE_DIVEXACT_BY3 }, { TRY(mpn_divexact_by3c), TYPE_DIVEXACT_BY3C }, { TRY_FUNFUN(mpn_modexact_1_odd), TYPE_MODEXACT_1_ODD }, { TRY(mpn_modexact_1c_odd), TYPE_MODEXACT_1C_ODD }, { TRY(mpn_sb_divrem_mn), TYPE_SB_DIVREM_MN, 3}, { TRY(mpn_tdiv_qr), TYPE_TDIV_QR }, { TRY(mpn_mul_1), TYPE_MUL_1 },#if HAVE_NATIVE_mpn_mul_1c { TRY(mpn_mul_1c), TYPE_MUL_1C },#endif#if HAVE_NATIVE_mpn_mul_2 { TRY(mpn_mul_2), TYPE_MUL_2 },#endif { TRY(mpn_rshift), TYPE_RSHIFT }, { TRY(mpn_lshift), TYPE_LSHIFT }, { TRY(mpn_mul_basecase), TYPE_MUL_BASECASE }, { TRY(mpn_sqr_basecase), TYPE_SQR }, { TRY(mpn_mul), TYPE_MUL_BASECASE }, { TRY(mpn_mul_n), TYPE_MUL_N }, { TRY(mpn_sqr_n), TYPE_SQR }, { TRY_FUNFUN(umul_ppmm), TYPE_UMUL_PPMM, 2 }, { TRY_FUNFUN(mpn_kara_mul_n), TYPE_MUL_N, MPN_KARA_MUL_N_MINSIZE }, { TRY_FUNFUN(mpn_kara_sqr_n), TYPE_SQR, MPN_KARA_SQR_N_MINSIZE }, { TRY_FUNFUN(mpn_toom3_mul_n), TYPE_MUL_N, MPN_TOOM3_MUL_N_MINSIZE }, { TRY_FUNFUN(mpn_toom3_sqr_n), TYPE_SQR, MPN_TOOM3_SQR_N_MINSIZE }, { TRY(mpn_gcd_1), TYPE_GCD_1 }, { TRY(mpn_gcd), TYPE_GCD },#if HAVE_NATIVE_mpn_gcd_finda { TRY(mpn_gcd_finda), TYPE_GCD_FINDA },#endif { TRY(mpz_jacobi), TYPE_MPZ_JACOBI }, { TRY(mpz_kronecker_ui), TYPE_MPZ_KRONECKER_UI }, { TRY(mpz_kronecker_si), TYPE_MPZ_KRONECKER_SI }, { TRY(mpz_ui_kronecker), TYPE_MPZ_UI_KRONECKER }, { TRY(mpz_si_kronecker), TYPE_MPZ_SI_KRONECKER }, { TRY(mpn_popcount), TYPE_POPCOUNT }, { TRY(mpn_hamdist), TYPE_HAMDIST }, { TRY(mpn_sqrtrem), TYPE_SQRTREM }, { TRY_FUNFUN(MPN_ZERO), TYPE_ZERO }, { TRY(mpn_get_str), TYPE_GET_STR },#ifdef EXTRA_ROUTINES EXTRA_ROUTINES#endif};const struct choice_t *choice = NULL;voidmprotect_maybe (void *addr, size_t len, int prot){ if (!option_redzones) return;#if HAVE_MPROTECT if (mprotect (addr, len, prot) != 0) { fprintf (stderr, "Cannot mprotect %p 0x%X 0x%X\n", addr, len, prot); exit (1); }#else { static int warned = 0; if (!warned) { fprintf (stderr, "mprotect not available, bounds testing not performed\n"); warned = 1; } }#endif}/* round "a" up to a multiple of "m" */size_tround_up_multiple (size_t a, size_t m){ unsigned long r; r = a % m; if (r == 0) return a; else return a + (m - r);}/* On some systems it seems that only an mmap'ed region can be mprotect'ed, for instance HP-UX 10. mmap will almost certainly return a pointer already aligned to a page boundary, but it's easy enough to share the alignment handling with the malloc case. */voidmalloc_region (struct region_t *r, mp_size_t n){ mp_ptr p; size_t nbytes; ASSERT ((pagesize % BYTES_PER_MP_LIMB) == 0); n = round_up_multiple (n, PAGESIZE_LIMBS); r->size = n; nbytes = n*BYTES_PER_MP_LIMB + 2*REDZONE_BYTES + pagesize;#if defined (MAP_ANONYMOUS) && ! defined (MAP_ANON)#define MAP_ANON MAP_ANONYMOUS#endif#if HAVE_MMAP && defined (MAP_ANON) /* note must pass fd=-1 for MAP_ANON on BSD */ p = mmap (NULL, nbytes, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); if (p == (void *) -1) { fprintf (stderr, "Cannot mmap %#x anon bytes\n", nbytes); exit (1); }#else p = malloc (nbytes); ASSERT_ALWAYS (p != NULL);#endif p = align_pointer (p, pagesize); mprotect_maybe (p, REDZONE_BYTES, PROT_NONE); p += REDZONE_LIMBS; r->ptr = p; mprotect_maybe (p + n, REDZONE_BYTES, PROT_NONE);}voidmprotect_region (const struct region_t *r, int prot){ mprotect_maybe (r->ptr, r->size, prot);}/* First four entries must be 0,1,2,3 for the benefit of CARRY_BIT, CARRY_3, and CARRY_4 */mp_limb_t carry_array[] = { 0, 1, 2, 3, 4, CNST_LIMB(1) << 8, CNST_LIMB(1) << 16, GMP_NUMB_MAX};int carry_index;#define CARRY_COUNT \ ((tr->carry == CARRY_BIT) ? 2 \ : tr->carry == CARRY_3 ? 3 \ : tr->carry == CARRY_4 ? 4 \ : (tr->carry == CARRY_LIMB || tr->carry == CARRY_DIVISOR) \ ? numberof(carry_array) + CARRY_RANDOMS \ : 1)#define MPN_RANDOM_ALT(index,dst,size) \ (((index) & 1) ? refmpn_random (dst, size) : refmpn_random2 (dst, size))/* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have the same type */#define CARRY_ITERATION \ for (carry_index = 0; \ (carry_index < numberof (carry_array) \ ? (carry = carry_array[carry_index]) \ : (MPN_RANDOM_ALT (carry_index, &carry, 1), (mp_limb_t) 0)), \ (tr->carry == CARRY_DIVISOR ? carry %= divisor : 0), \ carry_index < CARRY_COUNT; \ carry_index++)mp_limb_t multiplier_array[] = { 0, 1, 2, 3, CNST_LIMB(1) << 8, CNST_LIMB(1) << 16, GMP_NUMB_MAX - 2, GMP_NUMB_MAX - 1, GMP_NUMB_MAX};int multiplier_index;mp_limb_t divisor_array[] = { 1, 2, 3, CNST_LIMB(1) << 8, CNST_LIMB(1) << 16, GMP_NUMB_HIGHBIT, GMP_NUMB_HIGHBIT + 1, GMP_NUMB_MAX - 2, GMP_NUMB_MAX - 1, GMP_NUMB_MAX};int divisor_index;/* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have the same type */#define ARRAY_ITERATION(var, index, limit, array, randoms, cond) \ for (index = 0; \ (index < numberof (array) \ ? (var = array[index]) \ : (MPN_RANDOM_ALT (index, &var, 1), (mp_limb_t) 0)), \ index < limit; \ index++)#define MULTIPLIER_COUNT \ (tr->multiplier \ ? numberof (multiplier_array) + MULTIPLIER_RANDOMS \ : 1)#define MULTIPLIER_ITERATION \ ARRAY_ITERATION(multiplier, multiplier_index, MULTIPLIER_COUNT, \ multiplier_array, MULTIPLIER_RANDOMS, TRY_MULTIPLIER)#define DIVISOR_COUNT \ (tr->divisor \ ? numberof (divisor_array) + DIVISOR_RANDOMS \ : 1)#define DIVISOR_ITERATION \ ARRAY_ITERATION(divisor, divisor_index, DIVISOR_COUNT, divisor_array, \ DIVISOR_RANDOMS, TRY_DIVISOR)/* overlap_array[].s[i] is where s[i] should be, 0 or 1 means overlapping d[0] or d[1] respectively, -1 means a separate (write-protected) location. */struct overlap_t { int s[NUM_SOURCES];} overlap_array[] = { { { -1, -1 } }, { { 0, -1 } }, { { -1, 0 } }, { { 0, 0 } }, { { 1, -1 } }, { { -1, 1 } }, { { 1, 1 } }, { { 0, 1 } }, { { 1, 0 } },};struct overlap_t *overlap, *overlap_limit;#define OVERLAP_COUNT \ (tr->overlap & OVERLAP_NONE ? 1 \ : tr->overlap & OVERLAP_NOT_SRCS ? 3 \ : tr->overlap & OVERLAP_NOT_SRC2 ? 2 \ : tr->dst[1] ? 9 \ : tr->src[1] ? 4 \ : tr->dst[0] ? 2 \ : 1)#define OVERLAP_ITERATION \ for (overlap = &overlap_array[0], \ overlap_limit = &overlap_array[OVERLAP_COUNT]; \ overlap < overlap_limit; \ overlap++)int base = 10;#define T_RAND_COUNT 2int t_rand;voidt_random (mp_ptr ptr, mp_size_t n){ if (n == 0) return; switch (option_data) { case DATA_TRAND: switch (t_rand) { case 0: refmpn_random (ptr, n); break; case 1: refmpn_random2 (ptr, n); break; default: abort(); } break; case DATA_SEQ: { static mp_limb_t counter = 0; mp_size_t i; for (i = 0; i < n; i++) ptr[i] = ++counter; } break; case DATA_ZEROS: refmpn_zero (ptr, n); break; case DATA_FFS: refmpn_fill (ptr, n, GMP_NUMB_MAX); break; case DATA_2FD: /* Special value 0x2FFF...FFFD, which divided by 3 gives 0xFFF...FFF, inducing the q1_ff special case in the mul-by-inverse part of some versions of divrem_1 and mod_1. */ refmpn_fill (ptr, n, (mp_limb_t) -1); ptr[n-1] = 2; ptr[0] -= 2; break; default: abort(); }}#define T_RAND_ITERATION \ for (t_rand = 0; t_rand < T_RAND_COUNT; t_rand++)void print_each (const struct each_t *e){ int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -