117683Spst/* mpn_lshift -- Shift left low level. 239291Sfenner 317683SpstCopyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. 417683Spst 517683SpstThis file is part of the GNU MP Library. 617683Spst 717683SpstThe GNU MP Library is free software; you can redistribute it and/or modify 817683Spstit under the terms of the GNU Lesser General Public License as published by 917683Spstthe Free Software Foundation; either version 2.1 of the License, or (at your 1017683Spstoption) any later version. 1117683Spst 1217683SpstThe GNU MP Library is distributed in the hope that it will be useful, but 1317683SpstWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1417683Spstor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 1517683SpstLicense for more details. 1617683Spst 1717683SpstYou should have received a copy of the GNU Lesser General Public License 1817683Spstalong with the GNU MP Library; see the file COPYING.LIB. If not, write to 1917683Spstthe Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 2017683SpstMA 02111-1307, USA. */ 2117683Spst 2217683Spst#include <config.h> 2317683Spst#include "gmp-impl.h" 2417683Spst 2517683Spst/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left 2617683Spst and store the USIZE least significant digits of the result at WP. 2717683Spst Return the bits shifted out from the most significant digit. 2817683Spst 2917683Spst Argument constraints: 3017683Spst 1. 0 < CNT < BITS_PER_MP_LIMB 3117683Spst 2. If the result is to be written over the input, WP must be >= UP. 3217683Spst*/ 3317683Spst 3417683Spstmp_limb_t 35127664Sbms#if __STDC__ 36214518Srpaulompn_lshift (register mp_ptr wp, 3717683Spst register mp_srcptr up, mp_size_t usize, 3817683Spst register unsigned int cnt) 3975107Sfenner#else 4075107Sfennermpn_lshift (wp, up, usize, cnt) 4175107Sfenner register mp_ptr wp; 4275107Sfenner register mp_srcptr up; 43127664Sbms mp_size_t usize; 44127664Sbms register unsigned int cnt; 45127664Sbms#endif 46214518Srpaulo{ 47214518Srpaulo register mp_limb_t high_limb, low_limb; 48214518Srpaulo register unsigned sh_1, sh_2; 49214518Srpaulo register mp_size_t i; 50214518Srpaulo mp_limb_t retval; 51214518Srpaulo 52214518Srpaulo#ifdef DEBUG 53214518Srpaulo if (usize == 0 || cnt == 0) 5417683Spst abort (); 55183102Scsjp#endif 56127664Sbms 5717683Spst sh_1 = cnt; 5817683Spst#if 0 5917683Spst if (sh_1 == 0) 6017683Spst { 61235426Sdelphij if (wp != up) 6217683Spst { 63127664Sbms /* Copy from high end to low end, to allow specified input/output 6498530Sfenner overlapping. */ 6598530Sfenner for (i = usize - 1; i >= 0; i--) 6617683Spst wp[i] = up[i]; 6717683Spst } 6817683Spst return 0; 6917683Spst } 7017683Spst#endif 71146768Ssam 72146768Ssam wp += 1; 73146768Ssam sh_2 = BITS_PER_MP_LIMB - sh_1; 74146768Ssam i = usize - 1; 7517683Spst low_limb = up[i]; 7617683Spst retval = low_limb >> sh_2; 77127664Sbms high_limb = low_limb; 78251129Sdelphij while (--i >= 0) 79251129Sdelphij { 80251129Sdelphij low_limb = up[i]; 81251129Sdelphij wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); 82251129Sdelphij high_limb = low_limb; 83251129Sdelphij } 84251129Sdelphij wp[i] = high_limb << sh_1; 85251129Sdelphij 86251129Sdelphij return retval; 87251129Sdelphij} 88251129Sdelphij