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