1/* mpn_redc_1.  Set cp[] <- up[]/R^n mod mp[].  Clobber up[].
2   mp[] is n limbs; up[] is 2n limbs.
3
4   THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE.  IT IS ONLY
5   SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
6
7Copyright (C) 2000, 2001, 2002, 2004, 2008, 2009 Free Software Foundation, Inc.
8
9This file is part of the GNU MP Library.
10
11The GNU MP Library is free software; you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation; either version 3 of the License, or (at your
14option) any later version.
15
16The GNU MP Library is distributed in the hope that it will be useful, but
17WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
19License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
23
24#include "gmp.h"
25#include "gmp-impl.h"
26
27void
28mpn_redc_1 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_limb_t invm)
29{
30  mp_size_t j;
31  mp_limb_t cy;
32
33  ASSERT (n > 0);
34  ASSERT_MPN (up, 2*n);
35
36  for (j = n - 1; j >= 0; j--)
37    {
38      cy = mpn_addmul_1 (up, mp, n, (up[0] * invm) & GMP_NUMB_MASK);
39      ASSERT (up[0] == 0);
40      up[0] = cy;
41      up++;
42    }
43  cy = mpn_add_n (rp, up, up - n, n);
44  if (cy != 0)
45    mpn_sub_n (rp, rp, mp, n);
46}
47