Home | History | Annotate | Line # | Download | only in generic
pow_1.c revision 1.1.1.3
      1      1.1  mrg /* mpn_pow_1 -- Compute powers R = U^exp.
      2      1.1  mrg 
      3      1.1  mrg    THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
      4      1.1  mrg    CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
      5      1.1  mrg    FUTURE GNU MP RELEASES.
      6      1.1  mrg 
      7  1.1.1.2  mrg Copyright 2002, 2014 Free Software Foundation, Inc.
      8      1.1  mrg 
      9      1.1  mrg This file is part of the GNU MP Library.
     10      1.1  mrg 
     11  1.1.1.2  mrg The GNU MP Library is free software; you can redistribute it and/or modify
     12  1.1.1.2  mrg it under the terms of either:
     13  1.1.1.2  mrg 
     14  1.1.1.2  mrg   * the GNU Lesser General Public License as published by the Free
     15  1.1.1.2  mrg     Software Foundation; either version 3 of the License, or (at your
     16  1.1.1.2  mrg     option) any later version.
     17  1.1.1.2  mrg 
     18  1.1.1.2  mrg or
     19  1.1.1.2  mrg 
     20  1.1.1.2  mrg   * the GNU General Public License as published by the Free Software
     21  1.1.1.2  mrg     Foundation; either version 2 of the License, or (at your option) any
     22  1.1.1.2  mrg     later version.
     23  1.1.1.2  mrg 
     24  1.1.1.2  mrg or both in parallel, as here.
     25      1.1  mrg 
     26      1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     27  1.1.1.2  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     28  1.1.1.2  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     29      1.1  mrg for more details.
     30      1.1  mrg 
     31  1.1.1.2  mrg You should have received copies of the GNU General Public License and the
     32  1.1.1.2  mrg GNU Lesser General Public License along with the GNU MP Library.  If not,
     33  1.1.1.2  mrg see https://www.gnu.org/licenses/.  */
     34      1.1  mrg 
     35      1.1  mrg 
     36      1.1  mrg #include "gmp-impl.h"
     37      1.1  mrg #include "longlong.h"
     38      1.1  mrg 
     39      1.1  mrg mp_size_t
     40      1.1  mrg mpn_pow_1 (mp_ptr rp, mp_srcptr bp, mp_size_t bn, mp_limb_t exp, mp_ptr tp)
     41      1.1  mrg {
     42      1.1  mrg   mp_limb_t x;
     43      1.1  mrg   int cnt, i;
     44      1.1  mrg   mp_size_t rn;
     45      1.1  mrg   int par;
     46      1.1  mrg 
     47      1.1  mrg   ASSERT (bn >= 1);
     48      1.1  mrg   /* FIXME: Add operand overlap criteria */
     49      1.1  mrg 
     50      1.1  mrg   if (exp <= 1)
     51      1.1  mrg     {
     52      1.1  mrg       if (exp == 0)
     53      1.1  mrg 	{
     54      1.1  mrg 	  rp[0] = 1;
     55      1.1  mrg 	  return 1;
     56      1.1  mrg 	}
     57      1.1  mrg       else
     58      1.1  mrg 	{
     59      1.1  mrg 	  MPN_COPY (rp, bp, bn);
     60      1.1  mrg 	  return bn;
     61      1.1  mrg 	}
     62      1.1  mrg     }
     63      1.1  mrg 
     64      1.1  mrg   /* Count number of bits in exp, and compute where to put initial square in
     65      1.1  mrg      order to magically get results in the entry rp.  Use simple code,
     66      1.1  mrg      optimized for small exp.  For large exp, the bignum operations will take
     67      1.1  mrg      so much time that the slowness of this code will be negligible.  */
     68      1.1  mrg   par = 0;
     69      1.1  mrg   cnt = GMP_LIMB_BITS;
     70  1.1.1.2  mrg   x = exp;
     71  1.1.1.2  mrg   do
     72      1.1  mrg     {
     73  1.1.1.2  mrg       par ^= x;
     74      1.1  mrg       cnt--;
     75  1.1.1.2  mrg       x >>= 1;
     76  1.1.1.2  mrg     } while (x != 0);
     77      1.1  mrg   exp <<= cnt;
     78      1.1  mrg 
     79      1.1  mrg   if (bn == 1)
     80      1.1  mrg     {
     81  1.1.1.3  mrg       mp_limb_t rl, rh, bl = bp[0];
     82      1.1  mrg 
     83      1.1  mrg       if ((cnt & 1) != 0)
     84      1.1  mrg 	MP_PTR_SWAP (rp, tp);
     85      1.1  mrg 
     86  1.1.1.3  mrg       umul_ppmm (rh, rl, bl, bl << GMP_NAIL_BITS);
     87  1.1.1.3  mrg       rp[0] = rl >> GMP_NAIL_BITS;
     88  1.1.1.3  mrg       rp[1] = rh;
     89  1.1.1.3  mrg       rn = 1 + (rh != 0);
     90      1.1  mrg 
     91      1.1  mrg       for (i = GMP_LIMB_BITS - cnt - 1;;)
     92      1.1  mrg 	{
     93      1.1  mrg 	  exp <<= 1;
     94      1.1  mrg 	  if ((exp & GMP_LIMB_HIGHBIT) != 0)
     95      1.1  mrg 	    {
     96  1.1.1.3  mrg 	      rp[rn] = rh = mpn_mul_1 (rp, rp, rn, bl);
     97  1.1.1.3  mrg 	      rn += rh != 0;
     98      1.1  mrg 	    }
     99      1.1  mrg 
    100      1.1  mrg 	  if (--i == 0)
    101      1.1  mrg 	    break;
    102      1.1  mrg 
    103      1.1  mrg 	  mpn_sqr (tp, rp, rn);
    104      1.1  mrg 	  rn = 2 * rn; rn -= tp[rn - 1] == 0;
    105      1.1  mrg 	  MP_PTR_SWAP (rp, tp);
    106      1.1  mrg 	}
    107      1.1  mrg     }
    108      1.1  mrg   else
    109      1.1  mrg     {
    110      1.1  mrg       if (((par ^ cnt) & 1) == 0)
    111      1.1  mrg 	MP_PTR_SWAP (rp, tp);
    112      1.1  mrg 
    113      1.1  mrg       mpn_sqr (rp, bp, bn);
    114      1.1  mrg       rn = 2 * bn; rn -= rp[rn - 1] == 0;
    115      1.1  mrg 
    116      1.1  mrg       for (i = GMP_LIMB_BITS - cnt - 1;;)
    117      1.1  mrg 	{
    118      1.1  mrg 	  exp <<= 1;
    119      1.1  mrg 	  if ((exp & GMP_LIMB_HIGHBIT) != 0)
    120      1.1  mrg 	    {
    121      1.1  mrg 	      rn = rn + bn - (mpn_mul (tp, rp, rn, bp, bn) == 0);
    122      1.1  mrg 	      MP_PTR_SWAP (rp, tp);
    123      1.1  mrg 	    }
    124      1.1  mrg 
    125      1.1  mrg 	  if (--i == 0)
    126      1.1  mrg 	    break;
    127      1.1  mrg 
    128      1.1  mrg 	  mpn_sqr (tp, rp, rn);
    129      1.1  mrg 	  rn = 2 * rn; rn -= tp[rn - 1] == 0;
    130      1.1  mrg 	  MP_PTR_SWAP (rp, tp);
    131      1.1  mrg 	}
    132      1.1  mrg     }
    133      1.1  mrg 
    134      1.1  mrg   return rn;
    135      1.1  mrg }
    136