--- a/libgst/mpz.c +++ b/libgst/mpz.c @@ -1513,13 +1513,21 @@ _gst_mpz_xor (gst_mpz *res, const gst_mpz *op1, const gst_mpz *op2) } } +#if __GNU_MP_VERSION >= 5 +extern void __gmpn_divexact (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); +#endif + void _gst_mpz_divexact (gst_mpz *quot, const gst_mpz *num, const gst_mpz *den) { - mp_ptr qp, tp; + mp_ptr qp; mp_srcptr np, dp; - mp_size_t nsize, dsize, qsize, d_zero_limbs; + mp_size_t nsize, dsize, qsize; +#if __GNU_MP_VERSION < 5 + mp_ptr tp; + mp_size_t d_zero_limbs; int d_zero_bits; +#endif nsize = ABS (num->size); dsize = ABS (den->size); @@ -1542,6 +1550,7 @@ _gst_mpz_divexact (gst_mpz *quot, const gst_mpz *num, const gst_mpz *den) return; } +#if __GNU_MP_VERSION < 5 /* Avoid quadratic behaviour, but do it conservatively. */ if (nsize - dsize > 1500) { @@ -1560,6 +1569,7 @@ _gst_mpz_divexact (gst_mpz *quot, const gst_mpz *num, const gst_mpz *den) dsize -= d_zero_limbs; np += d_zero_limbs; nsize -= d_zero_limbs; +#endif /* Allocate where we place the result. It must be nsize limbs big because it also acts as a temporary area. */ @@ -1567,6 +1577,7 @@ _gst_mpz_divexact (gst_mpz *quot, const gst_mpz *num, const gst_mpz *den) gst_mpz_realloc (quot, nsize); qp = quot->d; +#if __GNU_MP_VERSION < 5 if (d_zero_bits != 0) { tp = (mp_ptr) alloca (dsize * SIZEOF_MP_LIMB_T); @@ -1579,9 +1590,14 @@ _gst_mpz_divexact (gst_mpz *quot, const gst_mpz *num, const gst_mpz *den) } else MPN_COPY(qp, np, nsize); +#endif qsize = nsize - dsize + 1; +#if __GNU_MP_VERSION < 5 mpn_bdivmod (qp, qp, nsize, dp, dsize, qsize * GMP_NUMB_BITS); +#else + __gmpn_divexact (qp, np, nsize, dp, dsize); +#endif quot->size = (num->size ^ den->size) >= 0 ? qsize : -qsize; }