1/* mpn_mul_1 -- Multiply a limb vector with a single limb and store the
2   product in a second limb vector.
3
4Copyright 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002 Free Software
5Foundation, Inc.
6
7This file is part of the GNU MP Library.
8
9The GNU MP Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 3 of the License, or (at your
12option) any later version.
13
14The GNU MP Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
21
22#include "gmp.h"
23#include "gmp-impl.h"
24#include "longlong.h"
25
26
27#if GMP_NAIL_BITS == 0
28
29mp_limb_t
30mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
31{
32  mp_limb_t ul, cl, hpl, lpl;
33
34  ASSERT (n >= 1);
35  ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
36
37  cl = 0;
38  do
39    {
40      ul = *up++;
41      umul_ppmm (hpl, lpl, ul, vl);
42
43      lpl += cl;
44      cl = (lpl < cl) + hpl;
45
46      *rp++ = lpl;
47    }
48  while (--n != 0);
49
50  return cl;
51}
52
53#endif
54
55#if GMP_NAIL_BITS >= 1
56
57mp_limb_t
58mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
59{
60  mp_limb_t shifted_vl, ul, lpl, hpl, prev_hpl, xw, cl, xl;
61
62  ASSERT (n >= 1);
63  ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
64  ASSERT_MPN (up, n);
65  ASSERT_LIMB (vl);
66
67  shifted_vl = vl << GMP_NAIL_BITS;
68  cl = 0;
69  prev_hpl = 0;
70  do
71    {
72      ul = *up++;
73
74      umul_ppmm (hpl, lpl, ul, shifted_vl);
75      lpl >>= GMP_NAIL_BITS;
76      xw = prev_hpl + lpl + cl;
77      cl = xw >> GMP_NUMB_BITS;
78      xl = xw & GMP_NUMB_MASK;
79      *rp++ = xl;
80      prev_hpl = hpl;
81    }
82  while (--n != 0);
83
84  return prev_hpl + cl;
85}
86
87#endif
88