Index: gcc/gmp/mpn/generic/mu_bdiv_q.c |
diff --git a/gcc/gmp/mpn/generic/mu_bdiv_q.c b/gcc/gmp/mpn/generic/mu_bdiv_q.c |
deleted file mode 100644 |
index 3b5f56d08830841545b40b8bf9fe85167913c5cb..0000000000000000000000000000000000000000 |
--- a/gcc/gmp/mpn/generic/mu_bdiv_q.c |
+++ /dev/null |
@@ -1,255 +0,0 @@ |
-/* mpn_mu_bdiv_q(qp,np,nn,dp,dn,tp) -- Compute {np,nn} / {dp,dn} mod B^nn. |
- storing the result in {qp,nn}. Overlap allowed between Q and N; all other |
- overlap disallowed. |
- |
- Contributed to the GNU project by Torbjorn Granlund. |
- |
- THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH A MUTABLE INTERFACE. IT IS |
- ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS |
- ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP |
- RELEASE. |
- |
-Copyright 2005, 2006, 2007 Free Software Foundation, Inc. |
- |
-This file is part of the GNU MP Library. |
- |
-The GNU MP Library is free software; you can redistribute it and/or modify |
-it under the terms of the GNU Lesser General Public License as published by |
-the Free Software Foundation; either version 3 of the License, or (at your |
-option) any later version. |
- |
-The GNU MP Library is distributed in the hope that it will be useful, but |
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
-or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
-License for more details. |
- |
-You should have received a copy of the GNU Lesser General Public License |
-along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ |
- |
- |
-/* We use the "misunderstanding algorithm" (MU), discovered by Paul Zimmermann |
- and Torbjorn Granlund when Torbjorn misunderstood Paul's explanation of |
- Jebelean's bidirectional exact division algorithm. |
- |
- The idea of this algorithm is to compute a smaller inverted value than used |
- in the standard Barrett algorithm, and thus save time in the Newton |
- iterations, and pay just a small price when using the inverted value for |
- developing quotient bits. |
- |
- Written by Torbjorn Granlund. Paul Zimmermann suggested the use of the |
- "wrap around" trick. |
-*/ |
- |
-#include "gmp.h" |
-#include "gmp-impl.h" |
- |
- |
-/* N = {np,nn} |
- D = {dp,dn} |
- |
- Requirements: N >= D |
- D >= 1 |
- N mod D = 0 |
- D odd |
- dn >= 2 |
- nn >= 2 |
- scratch space as determined by mpn_divexact_itch(nn,dn). |
- |
- Write quotient to Q = {qp,nn}. |
- |
- FIXME: When iterating, perhaps do the small step before loop, not after. |
- FIXME: Try to avoid the scalar divisions when computing inverse size. |
- FIXME: Trim allocation for (qn > dn) case, 3*dn might be possible. In |
- particular, when dn==in, tp and rp could use the same space. |
- FIXME: Trim final quotient calculation to qn limbs of precision. |
-*/ |
-void |
-mpn_mu_bdiv_q (mp_ptr qp, |
- mp_srcptr np, mp_size_t nn, |
- mp_srcptr dp, mp_size_t dn, |
- mp_ptr scratch) |
-{ |
- mp_ptr ip; |
- mp_ptr rp; |
- mp_size_t qn; |
- mp_size_t in; |
- |
- qn = nn; |
- |
- ASSERT (dn >= 2); |
- ASSERT (qn >= 2); |
- |
- if (qn > dn) |
- { |
- mp_size_t b; |
- mp_ptr tp; |
- mp_limb_t cy; |
- int k; |
- mp_size_t m, wn; |
- mp_size_t i; |
- |
- /* |_______________________| dividend |
- |________| divisor */ |
- |
- /* Compute an inverse size that is a nice partition of the quotient. */ |
- b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */ |
- in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */ |
- |
- /* Some notes on allocation: |
- |
- When in = dn, R dies when mpn_mullow returns, if in < dn the low in |
- limbs of R dies at that point. We could save memory by letting T live |
- just under R, and let the upper part of T expand into R. These changes |
- should reduce itch to perhaps 3dn. |
- */ |
- |
- ip = scratch; /* in limbs */ |
- rp = scratch + in; /* dn limbs */ |
- tp = scratch + in + dn; /* dn + in limbs FIXME: mpn_fft_next_size */ |
- scratch += in; /* Roughly 2in+1 limbs */ |
- |
- mpn_binvert (ip, dp, in, scratch); |
- |
- cy = 0; |
- |
- MPN_COPY (rp, np, dn); |
- np += dn; |
- mpn_mullow_n (qp, rp, ip, in); |
- qn -= in; |
- |
- if (ABOVE_THRESHOLD (dn, MUL_FFT_MODF_THRESHOLD)) |
- { |
- k = mpn_fft_best_k (dn, 0); |
- m = mpn_fft_next_size (dn, k); |
- wn = dn + in - m; /* number of wrapped limbs */ |
- ASSERT_ALWAYS (wn >= 0); /* could handle this below */ |
- } |
- |
- while (qn > in) |
- { |
-#if WANT_FFT |
- if (ABOVE_THRESHOLD (dn, MUL_FFT_MODF_THRESHOLD)) |
- { |
- /* The two multiplicands are dn and 'in' limbs, with dn >= in. |
- The relevant part of the result will typically partially wrap, |
- and that part will come out as subtracted to the right. The |
- unwrapped part, m-in limbs at the high end of tp, is the lower |
- part of the sought product. The wrapped part, at the low end |
- of tp, will be subtracted from the low part of the partial |
- remainder; we undo that operation with another subtraction. */ |
- int c0; |
- |
- mpn_mul_fft (tp, m, dp, dn, qp, in, k); |
- |
- c0 = mpn_sub_n (tp + m, rp, tp, wn); |
- |
- for (i = wn; c0 != 0 && i < in; i++) |
- c0 = tp[i] == GMP_NUMB_MASK; |
- mpn_incr_u (tp + in, c0); |
- } |
- else |
-#endif |
- mpn_mul (tp, dp, dn, qp, in); /* mulhi, need tp[dn+in-1...in] */ |
- qp += in; |
- if (dn != in) |
- { |
- /* Subtract tp[dn-1...in] from partial remainder. */ |
- cy += mpn_sub_n (rp, rp + in, tp + in, dn - in); |
- if (cy == 2) |
- { |
- mpn_incr_u (tp + dn, 1); |
- cy = 1; |
- } |
- } |
- /* Subtract tp[dn+in-1...dn] from dividend. */ |
- cy = mpn_sub_nc (rp + dn - in, np, tp + dn, in, cy); |
- np += in; |
- mpn_mullow_n (qp, rp, ip, in); |
- qn -= in; |
- } |
- |
- /* Generate last qn limbs. |
- FIXME: It should be possible to limit precision here, since qn is |
- typically somewhat smaller than dn. No big gains expected. */ |
-#if WANT_FFT |
- if (ABOVE_THRESHOLD (dn, MUL_FFT_MODF_THRESHOLD)) |
- { |
- int c0; |
- |
- mpn_mul_fft (tp, m, dp, dn, qp, in, k); |
- |
- c0 = mpn_sub_n (tp + m, rp, tp, wn); |
- |
- for (i = wn; c0 != 0 && i < in; i++) |
- c0 = tp[i] == GMP_NUMB_MASK; |
- mpn_incr_u (tp + in, c0); |
- } |
- else |
-#endif |
- mpn_mul (tp, dp, dn, qp, in); /* mulhi, need tp[qn+in-1...in] */ |
- qp += in; |
- if (dn != in) |
- { |
- cy += mpn_sub_n (rp, rp + in, tp + in, dn - in); |
- if (cy == 2) |
- { |
- mpn_incr_u (tp + dn, 1); |
- cy = 1; |
- } |
- } |
- |
- mpn_sub_nc (rp + dn - in, np, tp + dn, qn - (dn - in), cy); |
- mpn_mullow_n (qp, rp, ip, qn); |
- } |
- else |
- { |
- /* |_______________________| dividend |
- |________________| divisor */ |
- |
- /* Compute half-sized inverse. */ |
- in = qn - (qn >> 1); |
- |
- ip = scratch; /* ceil(qn/2) limbs */ |
- rp = scratch + in; /* ceil(qn/2)+qn limbs */ |
- scratch += in; /* 2*ceil(qn/2)+2 */ |
- |
- mpn_binvert (ip, dp, in, scratch); |
- |
- mpn_mullow_n (qp, np, ip, in); /* low `in' quotient limbs */ |
-#if WANT_FFT |
- if (ABOVE_THRESHOLD (qn, MUL_FFT_MODF_THRESHOLD)) |
- { |
- int k; |
- mp_size_t m; |
- |
- k = mpn_fft_best_k (qn, 0); |
- m = mpn_fft_next_size (qn, k); |
- mpn_mul_fft (rp, m, dp, qn, qp, in, k); |
- if (mpn_cmp (np, rp, in) < 0) |
- mpn_incr_u (rp + in, 1); |
- } |
- else |
-#endif |
- mpn_mul (rp, dp, qn, qp, in); /* mulhigh */ |
- |
- mpn_sub_n (rp, np + in, rp + in, qn - in); |
- mpn_mullow_n (qp + in, rp, ip, qn - in); /* high qn-in quotient limbs */ |
- } |
-} |
- |
-mp_size_t |
-mpn_mu_bdiv_q_itch (mp_size_t nn, mp_size_t dn) |
-{ |
- mp_size_t qn; |
- |
- qn = nn; |
- |
- if (qn > dn) |
- { |
- return 4 * dn; /* FIXME FIXME FIXME need mpn_fft_next_size */ |
- } |
- else |
- { |
- return 2 * qn + 1 + 2; /* FIXME FIXME FIXME need mpn_fft_next_size */ |
- } |
-} |