void mpn_mul_basecase (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn) { ASSERT (un >= vn); ASSERT (vn >= 1); ASSERT (! MPN_OVERLAP_P (rp, un+vn, up, un)); ASSERT (! MPN_OVERLAP_P (rp, un+vn, vp, vn)); /* We first multiply by the low order limb (or depending on optional function availability, limbs). This result can be stored, not added, to rp. We also avoid a loop for zeroing this way. */ #ifdef HAVE_NATIVE_mpn_mul_2 if (vn >= 2) { rp[un + 1] = mpn_mul_2 (rp, up, un, vp); rp += 2, vp += 2, vn -= 2; } else { rp[un] = mpn_mul_1 (rp, up, un, vp[0]); return; } #else rp[un] = mpn_mul_1 (rp, up, un, vp[0]); rp += 1, vp += 1, vn -= 1; #endif /* Now accumulate the product of up[] and the next higher limb (or depending on optional function availability, limbs) from vp[]. */ #define MAX_LEFT MP_SIZE_T_MAX /* Used to simplify loops into if statements */ #ifdef HAVE_NATIVE_mpn_addmul_6 while (vn >= 6) { rp[un + 6 - 1] = mpn_addmul_6 (rp, up, un, vp); if (MAX_LEFT == 6) return; rp += 6, vp += 6, vn -= 6; if (MAX_LEFT < 2 * 6) break; } #undef MAX_LEFT #define MAX_LEFT (6 - 1) #endif #ifdef HAVE_NATIVE_mpn_addmul_5 while (vn >= 5) { rp[un + 5 - 1] = mpn_addmul_5 (rp, up, un, vp); if (MAX_LEFT == 5) return; rp += 5, vp += 5, vn -= 5; if (MAX_LEFT < 2 * 5) break; } #undef MAX_LEFT #define MAX_LEFT (5 - 1) #endif #ifdef HAVE_NATIVE_mpn_addmul_4 while (vn >= 4) { rp[un + 4 - 1] = mpn_addmul_4 (rp, up, un, vp); if (MAX_LEFT == 4) return; rp += 4, vp += 4, vn -= 4; if (MAX_LEFT < 2 * 4) break; } #undef MAX_LEFT #define MAX_LEFT (4 - 1) #endif #ifdef HAVE_NATIVE_mpn_addmul_3 while (vn >= 3) { rp[un + 3 - 1] = mpn_addmul_3 (rp, up, un, vp); if (MAX_LEFT == 3) return; rp += 3, vp += 3, vn -= 3; if (MAX_LEFT < 2 * 3) break; } #undef MAX_LEFT #define MAX_LEFT (3 - 1) #endif #ifdef HAVE_NATIVE_mpn_addmul_2 while (vn >= 2) { rp[un + 2 - 1] = mpn_addmul_2 (rp, up, un, vp); if (MAX_LEFT == 2) return; rp += 2, vp += 2, vn -= 2; if (MAX_LEFT < 2 * 2) break; } #undef MAX_LEFT #define MAX_LEFT (2 - 1) #endif while (vn >= 1) { rp[un] = mpn_addmul_1 (rp, up, un, vp[0]); if (MAX_LEFT == 1) return; rp += 1, vp += 1, vn -= 1; } }
/* (rp, 2n) = (xp, n)*(yp, n) / B^n */ inline static void mpn_mulshort_n_basecase(mp_ptr rp, mp_srcptr xp, mp_srcptr yp, mp_size_t n) { mp_size_t i, k; ASSERT(n >= 3); /* this restriction doesn't make a lot of sense in general */ ASSERT_MPN(xp, n); ASSERT_MPN(yp, n); ASSERT(!MPN_OVERLAP_P (rp, 2 * n, xp, n)); ASSERT(!MPN_OVERLAP_P (rp, 2 * n, yp, n)); k = n - 2; /* so want short product sum_(i + j >= k) x[i]y[j]B^(i + j) */ i = 0; /* Multiply w limbs from y + i to (2 + i + w - 1) limbs from x + (n - 2 - i - w + 1) and put it into r + (n - 2 - w + 1), "overflow" (i.e. last) limb into r + (n + w - 1) for i between 0 and n - 2. i == n - w needs special treatment. */ /* We first multiply by the low order limb (or depending on optional function availability, limbs). This result can be stored, not added, to rp. We also avoid a loop for zeroing this way. */ #if HAVE_NATIVE_mpn_mul_2 rp[n + 1] = mpn_mul_2 (rp + k - 1, xp + k - 1, 2 + 1, yp); i += 2; #else rp[n] = mpn_mul_1 (rp + k, xp + k, 2, yp[0]); i += 1; #endif #if HAVE_NATIVE_mpn_addmul_6 while (i < n - 6) { rp[n + i + 6 - 1] = mpn_addmul_6 (rp + k - 6 + 1, xp + k - i - 6 + 1, 2 + i + 6 - 1, yp + i); i += 6; } if (i == n - 6) { rp[n + n - 1] = mpn_addmul_6 (rp + i, xp, n, yp + i); return; } #endif #if HAVE_NATIVE_mpn_addmul_5 while (i < n - 5) { rp[n + i + 5 - 1] = mpn_addmul_5 (rp + k - 5 + 1, xp + k - i - 5 + 1, 2 + i + 5 - 1, yp + i) i += 5; } if (i == n - 5) { rp[n + n - 1] = mpn_addmul_5 (rp + i, xp, n, yp + i); return; } #endif #if HAVE_NATIVE_mpn_addmul_4 while (i < n - 4) { rp[n + i + 4 - 1] = mpn_addmul_4 (rp + k - 4 + 1, xp + k - i - 4 + 1, 2 + i + 4 - 1, yp + i); i += 4; } if (i == n - 4) { rp[n + n - 1] = mpn_addmul_4 (rp + i, xp, n, yp + i); return; } #endif #if HAVE_NATIVE_mpn_addmul_3 while (i < n - 3) { rp[n + i + 3 - 1] = mpn_addmul_3 (rp + k - 3 + 1, xp + k - i - 3 + 1, 2 + i + 3 - 1, yp + i); i += 3; } if (i == n - 3) { rp[n + n - 1] = mpn_addmul_3 (rp + i, xp, n, yp + i); return; } #endif #if HAVE_NATIVE_mpn_addmul_2 while (i < n - 2) { rp[n + i + 2 - 1] = mpn_addmul_2 (rp + k - 2 + 1, xp + k - i - 2 + 1, 2 + i + 2 - 1, yp + i); i += 2; } if (i == n - 2) { rp[n + n - 1] = mpn_addmul_2 (rp + i, xp, n, yp + i); return; } #endif while (i < n - 1) { rp[n + i] = mpn_addmul_1 (rp + k, xp + k - i, 2 + i, yp[i]); i += 1; } rp[n + n - 1] = mpn_addmul_1 (rp + i, xp, n, yp[i]); return; }