151c586b8Smrg /* mpn_rshift -- Shift right low level.
251c586b8Smrg
3*ce543368Smrg Copyright 1991, 1993, 1994, 1996, 2000-2002 Free Software Foundation, Inc.
451c586b8Smrg
551c586b8Smrg This file is part of the GNU MP Library.
651c586b8Smrg
751c586b8Smrg The GNU MP Library is free software; you can redistribute it and/or modify
8*ce543368Smrg it under the terms of either:
9*ce543368Smrg
10*ce543368Smrg * the GNU Lesser General Public License as published by the Free
11*ce543368Smrg Software Foundation; either version 3 of the License, or (at your
1251c586b8Smrg option) any later version.
1351c586b8Smrg
14*ce543368Smrg or
15*ce543368Smrg
16*ce543368Smrg * the GNU General Public License as published by the Free Software
17*ce543368Smrg Foundation; either version 2 of the License, or (at your option) any
18*ce543368Smrg later version.
19*ce543368Smrg
20*ce543368Smrg or both in parallel, as here.
21*ce543368Smrg
2251c586b8Smrg The GNU MP Library is distributed in the hope that it will be useful, but
2351c586b8Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24*ce543368Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25*ce543368Smrg for more details.
2651c586b8Smrg
27*ce543368Smrg You should have received copies of the GNU General Public License and the
28*ce543368Smrg GNU Lesser General Public License along with the GNU MP Library. If not,
29*ce543368Smrg see https://www.gnu.org/licenses/. */
3051c586b8Smrg
3151c586b8Smrg #include "gmp-impl.h"
3251c586b8Smrg
3351c586b8Smrg /* Shift U (pointed to by up and N limbs long) cnt bits to the right
3451c586b8Smrg and store the n least significant limbs of the result at rp.
3551c586b8Smrg The bits shifted out to the right are returned.
3651c586b8Smrg
3751c586b8Smrg Argument constraints:
3851c586b8Smrg 1. 0 < cnt < GMP_NUMB_BITS.
3951c586b8Smrg 2. If the result is to be written over the input, rp must be <= up.
4051c586b8Smrg */
4151c586b8Smrg
4251c586b8Smrg mp_limb_t
mpn_rshift(mp_ptr rp,mp_srcptr up,mp_size_t n,unsigned int cnt)4351c586b8Smrg mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
4451c586b8Smrg {
4551c586b8Smrg mp_limb_t high_limb, low_limb;
4651c586b8Smrg unsigned int tnc;
4751c586b8Smrg mp_size_t i;
4851c586b8Smrg mp_limb_t retval;
4951c586b8Smrg
5051c586b8Smrg ASSERT (n >= 1);
5151c586b8Smrg ASSERT (cnt >= 1);
5251c586b8Smrg ASSERT (cnt < GMP_NUMB_BITS);
5351c586b8Smrg ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
5451c586b8Smrg
5551c586b8Smrg tnc = GMP_NUMB_BITS - cnt;
5651c586b8Smrg high_limb = *up++;
5751c586b8Smrg retval = (high_limb << tnc) & GMP_NUMB_MASK;
5851c586b8Smrg low_limb = high_limb >> cnt;
5951c586b8Smrg
6051c586b8Smrg for (i = n - 1; i != 0; i--)
6151c586b8Smrg {
6251c586b8Smrg high_limb = *up++;
6351c586b8Smrg *rp++ = low_limb | ((high_limb << tnc) & GMP_NUMB_MASK);
6451c586b8Smrg low_limb = high_limb >> cnt;
6551c586b8Smrg }
6651c586b8Smrg *rp = low_limb;
6751c586b8Smrg
6851c586b8Smrg return retval;
6951c586b8Smrg }
70