diff options
author | Kevin Ryde <user42@zip.com.au> | 2001-05-11 02:06:06 +0200 |
---|---|---|
committer | Kevin Ryde <user42@zip.com.au> | 2001-05-11 02:06:06 +0200 |
commit | 07acf17163074a5db3f3ba1732496a15a2c026bb (patch) | |
tree | 6ce27a50b6ff06f38fe7b69ad5afe8743bff5926 /mpz/mul.c | |
parent | 9afe2e10add092858f1488dabf6b5c14dc48cca1 (diff) | |
download | gmp-07acf17163074a5db3f3ba1732496a15a2c026bb.tar.gz |
* mpz/mul.c: Use mpn_mul_1 for size==1 and mpn_mul_2 (if available)
for size==2, to avoid copying; do vsize==0 test earlier.
Diffstat (limited to 'mpz/mul.c')
-rw-r--r-- | mpz/mul.c | 60 |
1 files changed, 45 insertions, 15 deletions
@@ -26,6 +26,7 @@ MA 02111-1307, USA. */ #include "mp.h" #endif + void #ifndef BERKELEY_MP mpz_mul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) @@ -39,23 +40,59 @@ mult (mpz_srcptr u, mpz_srcptr v, mpz_ptr w) mp_size_t sign_product; mp_ptr up, vp; mp_ptr wp; - mp_ptr free_me = NULL; + mp_ptr free_me; size_t free_me_size; mp_limb_t cy_limb; TMP_DECL (marker); - TMP_MARK (marker); sign_product = usize ^ vsize; usize = ABS (usize); vsize = ABS (vsize); if (usize < vsize) { - /* Swap U and V. */ - {const __mpz_struct *t = u; u = v; v = t;} - {mp_size_t t = usize; usize = vsize; vsize = t;} + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (usize, vsize); + } + + if (vsize == 0) + { + SIZ(w) = 0; + return; } +#if HAVE_NATIVE_mpn_mul_2 + if (vsize <= 2) + { + MPZ_REALLOC (w, usize+vsize); + wp = PTR(w); + if (vsize == 1) + cy_limb = mpn_mul_1 (wp, PTR(u), usize, PTR(v)[0]); + else + { + cy_limb = mpn_mul_2 (wp, PTR(u), usize, PTR(v)[0], PTR(v)[1]); + usize++; + } + wp[usize] = cy_limb; + usize += (cy_limb != 0); + SIZ(w) = (sign_product >= 0 ? usize : -usize); + return; + } +#else + if (vsize == 1) + { + MPZ_REALLOC (w, usize+1); + wp = PTR(w); + cy_limb = mpn_mul_1 (wp, PTR(u), usize, PTR(v)[0]); + wp[usize] = cy_limb; + usize += (cy_limb != 0); + SIZ(w) = (sign_product >= 0 ? usize : -usize); + return; + } +#endif + + TMP_MARK (marker); + free_me = NULL; up = u->_mp_d; vp = v->_mp_d; wp = w->_mp_d; @@ -98,16 +135,9 @@ mult (mpz_srcptr u, mpz_srcptr v, mpz_ptr w) } } - if (vsize == 0) - { - wsize = 0; - } - else - { - cy_limb = mpn_mul (wp, up, usize, vp, vsize); - wsize = usize + vsize; - wsize -= cy_limb == 0; - } + cy_limb = mpn_mul (wp, up, usize, vp, vsize); + wsize = usize + vsize; + wsize -= cy_limb == 0; w->_mp_size = sign_product < 0 ? -wsize : wsize; if (free_me != NULL) |