Annotation of OpenXM_contrib/gmp/mpz/mul.c, Revision 1.1.1.3
1.1 maekawa 1: /* mpz_mul -- Multiply two integers.
2:
1.1.1.3 ! ohara 3: Copyright 1991, 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc.
1.1 maekawa 4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2 maekawa 8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 maekawa 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 15: License for more details.
16:
1.1.1.2 maekawa 17: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
1.1.1.2 maekawa 22: #include <stdio.h> /* for NULL */
1.1 maekawa 23: #include "gmp.h"
24: #include "gmp-impl.h"
1.1.1.2 maekawa 25: #ifdef BERKELEY_MP
26: #include "mp.h"
27: #endif
1.1 maekawa 28:
1.1.1.3 ! ohara 29:
1.1 maekawa 30: void
1.1.1.3 ! ohara 31: #ifndef BERKELEY_MP
1.1 maekawa 32: mpz_mul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
33: #else /* BERKELEY_MP */
34: mult (mpz_srcptr u, mpz_srcptr v, mpz_ptr w)
35: #endif /* BERKELEY_MP */
36: {
37: mp_size_t usize = u->_mp_size;
38: mp_size_t vsize = v->_mp_size;
39: mp_size_t wsize;
40: mp_size_t sign_product;
41: mp_ptr up, vp;
42: mp_ptr wp;
1.1.1.3 ! ohara 43: mp_ptr free_me;
1.1 maekawa 44: size_t free_me_size;
45: mp_limb_t cy_limb;
46: TMP_DECL (marker);
47:
48: sign_product = usize ^ vsize;
49: usize = ABS (usize);
50: vsize = ABS (vsize);
51:
52: if (usize < vsize)
53: {
1.1.1.3 ! ohara 54: MPZ_SRCPTR_SWAP (u, v);
! 55: MP_SIZE_T_SWAP (usize, vsize);
1.1 maekawa 56: }
57:
1.1.1.3 ! ohara 58: if (vsize == 0)
! 59: {
! 60: SIZ(w) = 0;
! 61: return;
! 62: }
! 63:
! 64: #if HAVE_NATIVE_mpn_mul_2
! 65: if (vsize <= 2)
! 66: {
! 67: MPZ_REALLOC (w, usize+vsize);
! 68: wp = PTR(w);
! 69: if (vsize == 1)
! 70: cy_limb = mpn_mul_1 (wp, PTR(u), usize, PTR(v)[0]);
! 71: else
! 72: {
! 73: cy_limb = mpn_mul_2 (wp, PTR(u), usize, PTR(v));
! 74: usize++;
! 75: }
! 76: wp[usize] = cy_limb;
! 77: usize += (cy_limb != 0);
! 78: SIZ(w) = (sign_product >= 0 ? usize : -usize);
! 79: return;
! 80: }
! 81: #else
! 82: if (vsize == 1)
! 83: {
! 84: MPZ_REALLOC (w, usize+1);
! 85: wp = PTR(w);
! 86: cy_limb = mpn_mul_1 (wp, PTR(u), usize, PTR(v)[0]);
! 87: wp[usize] = cy_limb;
! 88: usize += (cy_limb != 0);
! 89: SIZ(w) = (sign_product >= 0 ? usize : -usize);
! 90: return;
! 91: }
! 92: #endif
! 93:
! 94: TMP_MARK (marker);
! 95: free_me = NULL;
1.1 maekawa 96: up = u->_mp_d;
97: vp = v->_mp_d;
98: wp = w->_mp_d;
99:
100: /* Ensure W has space enough to store the result. */
101: wsize = usize + vsize;
102: if (w->_mp_alloc < wsize)
103: {
104: if (wp == up || wp == vp)
105: {
106: free_me = wp;
107: free_me_size = w->_mp_alloc;
108: }
109: else
1.1.1.3 ! ohara 110: (*__gmp_free_func) (wp, w->_mp_alloc * BYTES_PER_MP_LIMB);
1.1 maekawa 111:
112: w->_mp_alloc = wsize;
1.1.1.3 ! ohara 113: wp = (mp_ptr) (*__gmp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
1.1 maekawa 114: w->_mp_d = wp;
115: }
116: else
117: {
118: /* Make U and V not overlap with W. */
119: if (wp == up)
120: {
121: /* W and U are identical. Allocate temporary space for U. */
122: up = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
123: /* Is V identical too? Keep it identical with U. */
124: if (wp == vp)
125: vp = up;
126: /* Copy to the temporary space. */
127: MPN_COPY (up, wp, usize);
128: }
129: else if (wp == vp)
130: {
131: /* W and V are identical. Allocate temporary space for V. */
132: vp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
133: /* Copy to the temporary space. */
134: MPN_COPY (vp, wp, vsize);
135: }
136: }
137:
1.1.1.3 ! ohara 138: cy_limb = mpn_mul (wp, up, usize, vp, vsize);
! 139: wsize = usize + vsize;
! 140: wsize -= cy_limb == 0;
1.1 maekawa 141:
142: w->_mp_size = sign_product < 0 ? -wsize : wsize;
143: if (free_me != NULL)
1.1.1.3 ! ohara 144: (*__gmp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
1.1 maekawa 145: TMP_FREE (marker);
146: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>