void fb_addd_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { mpn_xor_n(c, a, b, size); }
void fb_addn_low(dig_t *c, const dig_t *a, const dig_t *b) { mpn_xor_n(c, a, b, FB_DIGS); }
void check (void) { mp_limb_t wp[100], xp[100], yp[100]; mp_size_t size = 100; refmpn_zero (xp, size); refmpn_zero (yp, size); refmpn_zero (wp, size); pre ("mpn_add_n"); mpn_add_n (wp, xp, yp, size); post (); #if HAVE_NATIVE_mpn_add_nc pre ("mpn_add_nc"); mpn_add_nc (wp, xp, yp, size, CNST_LIMB(0)); post (); #endif #if HAVE_NATIVE_mpn_addlsh1_n pre ("mpn_addlsh1_n"); mpn_addlsh1_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_and_n pre ("mpn_and_n"); mpn_and_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_andn_n pre ("mpn_andn_n"); mpn_andn_n (wp, xp, yp, size); post (); #endif pre ("mpn_addmul_1"); mpn_addmul_1 (wp, xp, size, yp[0]); post (); #if HAVE_NATIVE_mpn_addmul_1c pre ("mpn_addmul_1c"); mpn_addmul_1c (wp, xp, size, yp[0], CNST_LIMB(0)); post (); #endif #if HAVE_NATIVE_mpn_com_n pre ("mpn_com_n"); mpn_com_n (wp, xp, size); post (); #endif #if HAVE_NATIVE_mpn_copyd pre ("mpn_copyd"); mpn_copyd (wp, xp, size); post (); #endif #if HAVE_NATIVE_mpn_copyi pre ("mpn_copyi"); mpn_copyi (wp, xp, size); post (); #endif pre ("mpn_divexact_1"); mpn_divexact_1 (wp, xp, size, CNST_LIMB(123)); post (); pre ("mpn_divexact_by3c"); mpn_divexact_by3c (wp, xp, size, CNST_LIMB(0)); post (); pre ("mpn_divrem_1"); mpn_divrem_1 (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123)); post (); #if HAVE_NATIVE_mpn_divrem_1c pre ("mpn_divrem_1c"); mpn_divrem_1c (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123), CNST_LIMB(122)); post (); #endif pre ("mpn_gcd_1"); xp[0] |= 1; notdead += (unsigned long) mpn_gcd_1 (xp, size, CNST_LIMB(123)); post (); #if HAVE_NATIVE_mpn_gcd_finda pre ("mpn_gcd_finda"); xp[0] |= 1; xp[1] |= 1; notdead += mpn_gcd_finda (xp); post (); #endif pre ("mpn_hamdist"); notdead += mpn_hamdist (xp, yp, size); post (); #if HAVE_NATIVE_mpn_ior_n pre ("mpn_ior_n"); mpn_ior_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_iorn_n pre ("mpn_iorn_n"); mpn_iorn_n (wp, xp, yp, size); post (); #endif pre ("mpn_lshift"); mpn_lshift (wp, xp, size, 1); post (); pre ("mpn_mod_1"); notdead += mpn_mod_1 (xp, size, CNST_LIMB(123)); post (); #if HAVE_NATIVE_mpn_mod_1c pre ("mpn_mod_1c"); notdead += mpn_mod_1c (xp, size, CNST_LIMB(123), CNST_LIMB(122)); post (); #endif #if GMP_NUMB_BITS % 4 == 0 pre ("mpn_mod_34lsub1"); notdead += mpn_mod_34lsub1 (xp, size); post (); #endif pre ("mpn_modexact_1_odd"); notdead += mpn_modexact_1_odd (xp, size, CNST_LIMB(123)); post (); pre ("mpn_modexact_1c_odd"); notdead += mpn_modexact_1c_odd (xp, size, CNST_LIMB(123), CNST_LIMB(456)); post (); pre ("mpn_mul_1"); mpn_mul_1 (wp, xp, size, yp[0]); post (); #if HAVE_NATIVE_mpn_mul_1c pre ("mpn_mul_1c"); mpn_mul_1c (wp, xp, size, yp[0], CNST_LIMB(0)); post (); #endif #if HAVE_NATIVE_mpn_mul_2 pre ("mpn_mul_2"); mpn_mul_2 (wp, xp, size-1, yp); post (); #endif pre ("mpn_mul_basecase"); mpn_mul_basecase (wp, xp, (mp_size_t) 3, yp, (mp_size_t) 3); post (); #if HAVE_NATIVE_mpn_nand_n pre ("mpn_nand_n"); mpn_nand_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_nior_n pre ("mpn_nior_n"); mpn_nior_n (wp, xp, yp, size); post (); #endif pre ("mpn_popcount"); notdead += mpn_popcount (xp, size); post (); pre ("mpn_preinv_mod_1"); notdead += mpn_preinv_mod_1 (xp, size, GMP_NUMB_MAX, refmpn_invert_limb (GMP_NUMB_MAX)); post (); #if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1 pre ("mpn_preinv_divrem_1"); mpn_preinv_divrem_1 (wp, (mp_size_t) 0, xp, size, GMP_NUMB_MAX, refmpn_invert_limb (GMP_NUMB_MAX), 0); post (); #endif #if HAVE_NATIVE_mpn_rsh1add_n pre ("mpn_rsh1add_n"); mpn_rsh1add_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_rsh1sub_n pre ("mpn_rsh1sub_n"); mpn_rsh1sub_n (wp, xp, yp, size); post (); #endif pre ("mpn_rshift"); mpn_rshift (wp, xp, size, 1); post (); pre ("mpn_sqr_basecase"); mpn_sqr_basecase (wp, xp, (mp_size_t) 3); post (); pre ("mpn_submul_1"); mpn_submul_1 (wp, xp, size, yp[0]); post (); #if HAVE_NATIVE_mpn_submul_1c pre ("mpn_submul_1c"); mpn_submul_1c (wp, xp, size, yp[0], CNST_LIMB(0)); post (); #endif pre ("mpn_sub_n"); mpn_sub_n (wp, xp, yp, size); post (); #if HAVE_NATIVE_mpn_sub_nc pre ("mpn_sub_nc"); mpn_sub_nc (wp, xp, yp, size, CNST_LIMB(0)); post (); #endif #if HAVE_NATIVE_mpn_sublsh1_n pre ("mpn_sublsh1_n"); mpn_sublsh1_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_udiv_qrnnd pre ("mpn_udiv_qrnnd"); mpn_udiv_qrnnd (&wp[0], CNST_LIMB(122), xp[0], CNST_LIMB(123)); post (); #endif #if HAVE_NATIVE_mpn_udiv_qrnnd_r pre ("mpn_udiv_qrnnd_r"); mpn_udiv_qrnnd (CNST_LIMB(122), xp[0], CNST_LIMB(123), &wp[0]); post (); #endif #if HAVE_NATIVE_mpn_umul_ppmm pre ("mpn_umul_ppmm"); mpn_umul_ppmm (&wp[0], xp[0], yp[0]); post (); #endif #if HAVE_NATIVE_mpn_umul_ppmm_r pre ("mpn_umul_ppmm_r"); mpn_umul_ppmm_r (&wp[0], xp[0], yp[0]); post (); #endif #if HAVE_NATIVE_mpn_xor_n pre ("mpn_xor_n"); mpn_xor_n (wp, xp, yp, size); post (); #endif #if HAVE_NATIVE_mpn_xnor_n pre ("mpn_xnor_n"); mpn_xnor_n (wp, xp, yp, size); post (); #endif }
int main (int argc, char **argv) { mp_ptr ap, bp, rp, refp; mp_size_t max_n, n; gmp_randstate_ptr rands; long test, reps = 1000; TMP_SDECL; TMP_SMARK; tests_start (); TESTS_REPS (reps, argv, argc); rands = RANDS; max_n = 32; ap = TMP_SALLOC_LIMBS (max_n); bp = TMP_SALLOC_LIMBS (max_n); rp = TMP_SALLOC_LIMBS (max_n); refp = TMP_SALLOC_LIMBS (max_n); for (test = 0; test < reps; test++) { for (n = 1; n <= max_n; n++) { mpn_random2 (ap, n); mpn_random2 (bp, n); refmpn_and_n (refp, ap, bp, n); mpn_and_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "and_n"); refmpn_ior_n (refp, ap, bp, n); mpn_ior_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "ior_n"); refmpn_xor_n (refp, ap, bp, n); mpn_xor_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "xor_n"); refmpn_andn_n (refp, ap, bp, n); mpn_andn_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "andn_n"); refmpn_iorn_n (refp, ap, bp, n); mpn_iorn_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "iorn_n"); refmpn_nand_n (refp, ap, bp, n); mpn_nand_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "nand_n"); refmpn_nior_n (refp, ap, bp, n); mpn_nior_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "nior_n"); refmpn_xnor_n (refp, ap, bp, n); mpn_xnor_n (rp, ap, bp, n); check_one (refp, rp, ap, bp, n, "xnor_n"); refmpn_com (refp, ap, n); mpn_com (rp, ap, n); check_one (refp, rp, ap, bp, n, "com"); } } TMP_SFREE; tests_end (); return 0; }
void mpz_xor (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) { mp_srcptr op1_ptr, op2_ptr; mp_size_t op1_size, op2_size; mp_ptr res_ptr; mp_size_t res_size, res_alloc; TMP_DECL; TMP_MARK; op1_size = SIZ(op1); op2_size = SIZ(op2); op1_ptr = PTR(op1); op2_ptr = PTR(op2); res_ptr = PTR(res); if (op1_size >= 0) { if (op2_size >= 0) { if (op1_size >= op2_size) { if (ALLOC(res) < op1_size) { _mpz_realloc (res, op1_size); /* No overlapping possible: op1_ptr = PTR(op1); */ op2_ptr = PTR(op2); res_ptr = PTR(res); } if (res_ptr != op1_ptr) MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size); if (LIKELY (op2_size != 0)) mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op2_size); res_size = op1_size; } else { if (ALLOC(res) < op2_size) { _mpz_realloc (res, op2_size); op1_ptr = PTR(op1); /* No overlapping possible: op2_ptr = PTR(op2); */ res_ptr = PTR(res); } if (res_ptr != op2_ptr) MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); if (LIKELY (op1_size != 0)) mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size); res_size = op2_size; } MPN_NORMALIZE (res_ptr, res_size); SIZ(res) = res_size; return; } else /* op2_size < 0 */ { /* Fall through to the code at the end of the function. */ } } else { if (op2_size < 0) { mp_ptr opx, opy; /* Both operands are negative, the result will be positive. (-OP1) ^ (-OP2) = = ~(OP1 - 1) ^ ~(OP2 - 1) = = (OP1 - 1) ^ (OP2 - 1) */ op1_size = -op1_size; op2_size = -op2_size; /* Possible optimization: Decrease mpn_sub precision, as we won't use the entire res of both. */ TMP_ALLOC_LIMBS_2 (opx, op1_size, opy, op2_size); mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1); op1_ptr = opx; mpn_sub_1 (opy, op2_ptr, op2_size, (mp_limb_t) 1); op2_ptr = opy; if (op1_size > op2_size) MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size); res_alloc = op2_size; res_ptr = MPZ_REALLOC (res, res_alloc); MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size); res_size = op2_size; MPN_NORMALIZE (res_ptr, res_size); SIZ(res) = res_size; TMP_FREE; return; } else { /* We should compute -OP1 ^ OP2. Swap OP1 and OP2 and fall through to the code that handles OP1 ^ -OP2. */ MPZ_SRCPTR_SWAP (op1, op2); MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size); } } { mp_ptr opx; mp_limb_t cy; /* Operand 2 negative, so will be the result. -(OP1 ^ (-OP2)) = -(OP1 ^ ~(OP2 - 1)) = = ~(OP1 ^ ~(OP2 - 1)) + 1 = = (OP1 ^ (OP2 - 1)) + 1 */ op2_size = -op2_size; opx = TMP_ALLOC_LIMBS (op2_size); mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1); op2_ptr = opx; res_alloc = MAX (op1_size, op2_size) + 1; if (ALLOC(res) < res_alloc) { _mpz_realloc (res, res_alloc); op1_ptr = PTR(op1); /* op2_ptr points to temporary space. */ res_ptr = PTR(res); } if (op1_size > op2_size) { MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size); mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op2_size); res_size = op1_size; } else { MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); if (LIKELY (op1_size != 0)) mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size); res_size = op2_size; } cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1); res_ptr[res_size] = cy; res_size += (cy != 0); MPN_NORMALIZE (res_ptr, res_size); SIZ(res) = -res_size; TMP_FREE; } }