xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/printf/lshift.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg /* mpn_lshift -- Shift left low level.
2*627f7eb2Smrg 
3*627f7eb2Smrg Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
4*627f7eb2Smrg 
5*627f7eb2Smrg This file is part of the GNU MP Library.
6*627f7eb2Smrg 
7*627f7eb2Smrg The GNU MP Library is free software; you can redistribute it and/or modify
8*627f7eb2Smrg it under the terms of the GNU Lesser General Public License as published by
9*627f7eb2Smrg the Free Software Foundation; either version 2.1 of the License, or (at your
10*627f7eb2Smrg option) any later version.
11*627f7eb2Smrg 
12*627f7eb2Smrg The GNU MP Library is distributed in the hope that it will be useful, but
13*627f7eb2Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*627f7eb2Smrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15*627f7eb2Smrg License for more details.
16*627f7eb2Smrg 
17*627f7eb2Smrg You should have received a copy of the GNU Lesser General Public License
18*627f7eb2Smrg along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19*627f7eb2Smrg the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20*627f7eb2Smrg MA 02111-1307, USA. */
21*627f7eb2Smrg 
22*627f7eb2Smrg #include <config.h>
23*627f7eb2Smrg #include "gmp-impl.h"
24*627f7eb2Smrg 
25*627f7eb2Smrg /* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
26*627f7eb2Smrg    and store the USIZE least significant digits of the result at WP.
27*627f7eb2Smrg    Return the bits shifted out from the most significant digit.
28*627f7eb2Smrg 
29*627f7eb2Smrg    Argument constraints:
30*627f7eb2Smrg    1. 0 < CNT < BITS_PER_MP_LIMB
31*627f7eb2Smrg    2. If the result is to be written over the input, WP must be >= UP.
32*627f7eb2Smrg */
33*627f7eb2Smrg 
34*627f7eb2Smrg mp_limb_t
35*627f7eb2Smrg #if __STDC__
mpn_lshift(register mp_ptr wp,register mp_srcptr up,mp_size_t usize,register unsigned int cnt)36*627f7eb2Smrg mpn_lshift (register mp_ptr wp,
37*627f7eb2Smrg 	    register mp_srcptr up, mp_size_t usize,
38*627f7eb2Smrg 	    register unsigned int cnt)
39*627f7eb2Smrg #else
40*627f7eb2Smrg mpn_lshift (wp, up, usize, cnt)
41*627f7eb2Smrg      register mp_ptr wp;
42*627f7eb2Smrg      register mp_srcptr up;
43*627f7eb2Smrg      mp_size_t usize;
44*627f7eb2Smrg      register unsigned int cnt;
45*627f7eb2Smrg #endif
46*627f7eb2Smrg {
47*627f7eb2Smrg   register mp_limb_t high_limb, low_limb;
48*627f7eb2Smrg   register unsigned sh_1, sh_2;
49*627f7eb2Smrg   register mp_size_t i;
50*627f7eb2Smrg   mp_limb_t retval;
51*627f7eb2Smrg 
52*627f7eb2Smrg #ifdef DEBUG
53*627f7eb2Smrg   if (usize == 0 || cnt == 0)
54*627f7eb2Smrg     abort ();
55*627f7eb2Smrg #endif
56*627f7eb2Smrg 
57*627f7eb2Smrg   sh_1 = cnt;
58*627f7eb2Smrg #if 0
59*627f7eb2Smrg   if (sh_1 == 0)
60*627f7eb2Smrg     {
61*627f7eb2Smrg       if (wp != up)
62*627f7eb2Smrg 	{
63*627f7eb2Smrg 	  /* Copy from high end to low end, to allow specified input/output
64*627f7eb2Smrg 	     overlapping.  */
65*627f7eb2Smrg 	  for (i = usize - 1; i >= 0; i--)
66*627f7eb2Smrg 	    wp[i] = up[i];
67*627f7eb2Smrg 	}
68*627f7eb2Smrg       return 0;
69*627f7eb2Smrg     }
70*627f7eb2Smrg #endif
71*627f7eb2Smrg 
72*627f7eb2Smrg   wp += 1;
73*627f7eb2Smrg   sh_2 = BITS_PER_MP_LIMB - sh_1;
74*627f7eb2Smrg   i = usize - 1;
75*627f7eb2Smrg   low_limb = up[i];
76*627f7eb2Smrg   retval = low_limb >> sh_2;
77*627f7eb2Smrg   high_limb = low_limb;
78*627f7eb2Smrg   while (--i >= 0)
79*627f7eb2Smrg     {
80*627f7eb2Smrg       low_limb = up[i];
81*627f7eb2Smrg       wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
82*627f7eb2Smrg       high_limb = low_limb;
83*627f7eb2Smrg     }
84*627f7eb2Smrg   wp[i] = high_limb << sh_1;
85*627f7eb2Smrg 
86*627f7eb2Smrg   return retval;
87*627f7eb2Smrg }
88