1 /* mpn_redc_2. Set cp[] <- up[]/R^n mod mp[]. Clobber up[].
2 mp[] is n limbs; up[] is 2n limbs.
4 THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
5 SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
7 Copyright (C) 2000, 2001, 2002, 2004, 2008 Free Software Foundation, Inc.
9 This file is part of the GNU MP Library.
11 The GNU MP Library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 The GNU MP Library is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19 License for more details.
21 You should have received a copy of the GNU Lesser General Public License
22 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
29 #if GMP_NAIL_BITS != 0
33 /* For testing purposes, define our own mpn_addmul_2 if there is none already
35 #ifndef HAVE_NATIVE_mpn_addmul_2
37 mpn_addmul_2 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_srcptr vp)
39 rp[n] = mpn_addmul_1 (rp, up, n, vp[0]);
40 return mpn_addmul_1 (rp + 1, up, n, vp[1]);
44 #if defined (__ia64) && W_TYPE_SIZE == 64
45 #define umul2low(ph, pl, uh, ul, vh, vl) \
48 __asm__ ("xma.hu %0 = %3, %5, f0\n\t" \
49 "xma.l %1 = %3, %5, f0\n\t" \
51 "xma.l %0 = %3, %4, %0\n\t" \
53 "xma.l %0 = %2, %5, %0" \
54 : "=&f" (ph), "=&f" (pl) \
55 : "f" (uh), "f" (ul), "f" (vh), "f" (vl)); \
60 #define umul2low(ph, pl, uh, ul, vh, vl) \
63 umul_ppmm (_ph, _pl, ul, vl); \
64 (ph) = _ph + (ul) * (vh) + (uh) * (vl); \
70 mpn_redc_2 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_srcptr mip)
81 up[0] = mpn_addmul_1 (up, mp, n, (up[0] * mip[0]) & GMP_NUMB_MASK);
85 for (j = n - 2; j >= 0; j -= 2)
87 umul2low (q[1], q[0], mip[1], mip[0], up[1], up[0]);
88 upn = up[n]; /* mpn_addmul_2 overwrites this */
89 up[1] = mpn_addmul_2 (up, mp, n, q);
94 cy = mpn_add_n (rp, up, up - n, n);
96 mpn_sub_n (rp, rp, mp, n);