Back to index

glibc  2.9
lshift.c
Go to the documentation of this file.
00001 /* mpn_lshift -- Shift left low level.
00002 
00003 Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
00004 
00005 This file is part of the GNU MP Library.
00006 
00007 The GNU MP Library is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2.1 of the License, or (at your
00010 option) any later version.
00011 
00012 The GNU MP Library is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00014 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00015 License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
00019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00020 MA 02111-1307, USA. */
00021 
00022 #include <gmp.h>
00023 #include "gmp-impl.h"
00024 
00025 /* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
00026    and store the USIZE least significant digits of the result at WP.
00027    Return the bits shifted out from the most significant digit.
00028 
00029    Argument constraints:
00030    1. 0 < CNT < BITS_PER_MP_LIMB
00031    2. If the result is to be written over the input, WP must be >= UP.
00032 */
00033 
00034 mp_limb_t
00035 #if __STDC__
00036 mpn_lshift (register mp_ptr wp,
00037            register mp_srcptr up, mp_size_t usize,
00038            register unsigned int cnt)
00039 #else
00040 mpn_lshift (wp, up, usize, cnt)
00041      register mp_ptr wp;
00042      register mp_srcptr up;
00043      mp_size_t usize;
00044      register unsigned int cnt;
00045 #endif
00046 {
00047   register mp_limb_t high_limb, low_limb;
00048   register unsigned sh_1, sh_2;
00049   register mp_size_t i;
00050   mp_limb_t retval;
00051 
00052 #ifdef DEBUG
00053   if (usize == 0 || cnt == 0)
00054     abort ();
00055 #endif
00056 
00057   sh_1 = cnt;
00058 #if 0
00059   if (sh_1 == 0)
00060     {
00061       if (wp != up)
00062        {
00063          /* Copy from high end to low end, to allow specified input/output
00064             overlapping.  */
00065          for (i = usize - 1; i >= 0; i--)
00066            wp[i] = up[i];
00067        }
00068       return 0;
00069     }
00070 #endif
00071 
00072   wp += 1;
00073   sh_2 = BITS_PER_MP_LIMB - sh_1;
00074   i = usize - 1;
00075   low_limb = up[i];
00076   retval = low_limb >> sh_2;
00077   high_limb = low_limb;
00078   while (--i >= 0)
00079     {
00080       low_limb = up[i];
00081       wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
00082       high_limb = low_limb;
00083     }
00084   wp[i] = high_limb << sh_1;
00085 
00086   return retval;
00087 }