xref: /dflybsd-src/contrib/gmp/mpn/generic/set_str.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino /* mpn_set_str (mp_ptr res_ptr, const char *str, size_t str_len, int base) --
286d7f5d3SJohn Marino    Convert a STR_LEN long base BASE byte string pointed to by STR to a limb
386d7f5d3SJohn Marino    vector pointed to by RES_PTR.  Return the number of limbs in RES_PTR.
486d7f5d3SJohn Marino 
586d7f5d3SJohn Marino    Contributed to the GNU project by Torbjorn Granlund.
686d7f5d3SJohn Marino 
786d7f5d3SJohn Marino    THE FUNCTIONS IN THIS FILE, EXCEPT mpn_set_str, ARE INTERNAL WITH A MUTABLE
886d7f5d3SJohn Marino    INTERFACE.  IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES.  IN
986d7f5d3SJohn Marino    FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
1086d7f5d3SJohn Marino    GNU MP RELEASE.
1186d7f5d3SJohn Marino 
1286d7f5d3SJohn Marino Copyright 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 2004, 2006, 2007,
1386d7f5d3SJohn Marino 2008 Free Software Foundation, Inc.
1486d7f5d3SJohn Marino 
1586d7f5d3SJohn Marino This file is part of the GNU MP Library.
1686d7f5d3SJohn Marino 
1786d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
1886d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
1986d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
2086d7f5d3SJohn Marino option) any later version.
2186d7f5d3SJohn Marino 
2286d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
2386d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2486d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
2586d7f5d3SJohn Marino License for more details.
2686d7f5d3SJohn Marino 
2786d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
2886d7f5d3SJohn Marino along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
2986d7f5d3SJohn Marino 
3086d7f5d3SJohn Marino 
3186d7f5d3SJohn Marino /* TODO:
3286d7f5d3SJohn Marino 
3386d7f5d3SJohn Marino       Perhaps do not compute the highest power?
3486d7f5d3SJohn Marino       Instead, multiply twice by the 2nd highest power:
3586d7f5d3SJohn Marino 
3686d7f5d3SJohn Marino 	       _______
3786d7f5d3SJohn Marino 	      |_______|  hp
3886d7f5d3SJohn Marino 	      |_______|  pow
3986d7f5d3SJohn Marino        _______________
4086d7f5d3SJohn Marino       |_______________|  final result
4186d7f5d3SJohn Marino 
4286d7f5d3SJohn Marino 
4386d7f5d3SJohn Marino 	       _______
4486d7f5d3SJohn Marino 	      |_______|  hp
4586d7f5d3SJohn Marino 		  |___|  pow[-1]
4686d7f5d3SJohn Marino 	   ___________
4786d7f5d3SJohn Marino 	  |___________|  intermediate result
4886d7f5d3SJohn Marino 		  |___|  pow[-1]
4986d7f5d3SJohn Marino        _______________
5086d7f5d3SJohn Marino       |_______________|  final result
5186d7f5d3SJohn Marino 
5286d7f5d3SJohn Marino       Generalizing that idea, perhaps we should make powtab contain successive
5386d7f5d3SJohn Marino       cubes, not squares.
5486d7f5d3SJohn Marino */
5586d7f5d3SJohn Marino 
5686d7f5d3SJohn Marino #include "gmp.h"
5786d7f5d3SJohn Marino #include "gmp-impl.h"
5886d7f5d3SJohn Marino #include "longlong.h"
5986d7f5d3SJohn Marino 
6086d7f5d3SJohn Marino mp_size_t
mpn_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,int base)6186d7f5d3SJohn Marino mpn_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
6286d7f5d3SJohn Marino {
6386d7f5d3SJohn Marino   if (POW2_P (base))
6486d7f5d3SJohn Marino     {
6586d7f5d3SJohn Marino       /* The base is a power of 2.  Read the input string from least to most
6686d7f5d3SJohn Marino 	 significant character/digit.  */
6786d7f5d3SJohn Marino 
6886d7f5d3SJohn Marino       const unsigned char *s;
6986d7f5d3SJohn Marino       int next_bitpos;
7086d7f5d3SJohn Marino       mp_limb_t res_digit;
7186d7f5d3SJohn Marino       mp_size_t size;
7286d7f5d3SJohn Marino       int bits_per_indigit = mp_bases[base].big_base;
7386d7f5d3SJohn Marino 
7486d7f5d3SJohn Marino       size = 0;
7586d7f5d3SJohn Marino       res_digit = 0;
7686d7f5d3SJohn Marino       next_bitpos = 0;
7786d7f5d3SJohn Marino 
7886d7f5d3SJohn Marino       for (s = str + str_len - 1; s >= str; s--)
7986d7f5d3SJohn Marino 	{
8086d7f5d3SJohn Marino 	  int inp_digit = *s;
8186d7f5d3SJohn Marino 
8286d7f5d3SJohn Marino 	  res_digit |= ((mp_limb_t) inp_digit << next_bitpos) & GMP_NUMB_MASK;
8386d7f5d3SJohn Marino 	  next_bitpos += bits_per_indigit;
8486d7f5d3SJohn Marino 	  if (next_bitpos >= GMP_NUMB_BITS)
8586d7f5d3SJohn Marino 	    {
8686d7f5d3SJohn Marino 	      rp[size++] = res_digit;
8786d7f5d3SJohn Marino 	      next_bitpos -= GMP_NUMB_BITS;
8886d7f5d3SJohn Marino 	      res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
8986d7f5d3SJohn Marino 	    }
9086d7f5d3SJohn Marino 	}
9186d7f5d3SJohn Marino 
9286d7f5d3SJohn Marino       if (res_digit != 0)
9386d7f5d3SJohn Marino 	rp[size++] = res_digit;
9486d7f5d3SJohn Marino       return size;
9586d7f5d3SJohn Marino     }
9686d7f5d3SJohn Marino 
9786d7f5d3SJohn Marino   if (BELOW_THRESHOLD (str_len, SET_STR_PRECOMPUTE_THRESHOLD))
9886d7f5d3SJohn Marino     return mpn_bc_set_str (rp, str, str_len, base);
9986d7f5d3SJohn Marino   else
10086d7f5d3SJohn Marino     {
10186d7f5d3SJohn Marino       mp_ptr powtab_mem, tp;
10286d7f5d3SJohn Marino       powers_t powtab[GMP_LIMB_BITS];
10386d7f5d3SJohn Marino       int chars_per_limb;
10486d7f5d3SJohn Marino       mp_size_t size;
10586d7f5d3SJohn Marino       mp_size_t un;
10686d7f5d3SJohn Marino       TMP_DECL;
10786d7f5d3SJohn Marino 
10886d7f5d3SJohn Marino       TMP_MARK;
10986d7f5d3SJohn Marino 
11086d7f5d3SJohn Marino       chars_per_limb = mp_bases[base].chars_per_limb;
11186d7f5d3SJohn Marino 
11286d7f5d3SJohn Marino       un = str_len / chars_per_limb + 1;
11386d7f5d3SJohn Marino 
11486d7f5d3SJohn Marino       /* Allocate one large block for the powers of big_base.  */
11586d7f5d3SJohn Marino       powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_set_str_powtab_alloc (un));
11686d7f5d3SJohn Marino 
11786d7f5d3SJohn Marino       mpn_set_str_compute_powtab (powtab, powtab_mem, un, base);
11886d7f5d3SJohn Marino 
11986d7f5d3SJohn Marino       tp = TMP_BALLOC_LIMBS (mpn_dc_set_str_itch (un));
12086d7f5d3SJohn Marino       size = mpn_dc_set_str (rp, str, str_len, powtab, tp);
12186d7f5d3SJohn Marino 
12286d7f5d3SJohn Marino       TMP_FREE;
12386d7f5d3SJohn Marino       return size;
12486d7f5d3SJohn Marino     }
12586d7f5d3SJohn Marino }
12686d7f5d3SJohn Marino 
12786d7f5d3SJohn Marino void
mpn_set_str_compute_powtab(powers_t * powtab,mp_ptr powtab_mem,mp_size_t un,int base)12886d7f5d3SJohn Marino mpn_set_str_compute_powtab (powers_t *powtab, mp_ptr powtab_mem, mp_size_t un, int base)
12986d7f5d3SJohn Marino {
13086d7f5d3SJohn Marino   mp_ptr powtab_mem_ptr;
13186d7f5d3SJohn Marino   long i, pi;
13286d7f5d3SJohn Marino   mp_size_t n;
13386d7f5d3SJohn Marino   mp_ptr p, t;
13486d7f5d3SJohn Marino   unsigned normalization_steps;
13586d7f5d3SJohn Marino   mp_limb_t big_base, big_base_inverted;
13686d7f5d3SJohn Marino   int chars_per_limb;
13786d7f5d3SJohn Marino   size_t digits_in_base;
13886d7f5d3SJohn Marino   mp_size_t shift;
13986d7f5d3SJohn Marino 
14086d7f5d3SJohn Marino   powtab_mem_ptr = powtab_mem;
14186d7f5d3SJohn Marino 
14286d7f5d3SJohn Marino   chars_per_limb = mp_bases[base].chars_per_limb;
14386d7f5d3SJohn Marino   big_base = mp_bases[base].big_base;
14486d7f5d3SJohn Marino   big_base_inverted = mp_bases[base].big_base_inverted;
14586d7f5d3SJohn Marino   count_leading_zeros (normalization_steps, big_base);
14686d7f5d3SJohn Marino 
14786d7f5d3SJohn Marino   p = powtab_mem_ptr;
14886d7f5d3SJohn Marino   powtab_mem_ptr += 1;
14986d7f5d3SJohn Marino 
15086d7f5d3SJohn Marino   digits_in_base = chars_per_limb;
15186d7f5d3SJohn Marino 
15286d7f5d3SJohn Marino   p[0] = big_base;
15386d7f5d3SJohn Marino   n = 1;
15486d7f5d3SJohn Marino 
15586d7f5d3SJohn Marino   count_leading_zeros (i, un - 1);
15686d7f5d3SJohn Marino   i = GMP_LIMB_BITS - 1 - i;
15786d7f5d3SJohn Marino 
15886d7f5d3SJohn Marino   powtab[i].p = p;
15986d7f5d3SJohn Marino   powtab[i].n = n;
16086d7f5d3SJohn Marino   powtab[i].digits_in_base = digits_in_base;
16186d7f5d3SJohn Marino   powtab[i].base = base;
16286d7f5d3SJohn Marino   powtab[i].shift = 0;
16386d7f5d3SJohn Marino 
16486d7f5d3SJohn Marino   shift = 0;
16586d7f5d3SJohn Marino   for (pi = i - 1; pi >= 0; pi--)
16686d7f5d3SJohn Marino     {
16786d7f5d3SJohn Marino       t = powtab_mem_ptr;
16886d7f5d3SJohn Marino       powtab_mem_ptr += 2 * n;
16986d7f5d3SJohn Marino 
17086d7f5d3SJohn Marino       ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_set_str_powtab_alloc (un));
17186d7f5d3SJohn Marino 
17286d7f5d3SJohn Marino       mpn_sqr (t, p, n);
17386d7f5d3SJohn Marino       n = 2 * n - 1; n += t[n] != 0;
17486d7f5d3SJohn Marino       digits_in_base *= 2;
17586d7f5d3SJohn Marino #if 1
17686d7f5d3SJohn Marino       if ((((un - 1) >> pi) & 2) == 0)
17786d7f5d3SJohn Marino 	{
17886d7f5d3SJohn Marino 	  mpn_divexact_1 (t, t, n, big_base);
17986d7f5d3SJohn Marino 	  n -= t[n - 1] == 0;
18086d7f5d3SJohn Marino 	  digits_in_base -= chars_per_limb;
18186d7f5d3SJohn Marino 	}
18286d7f5d3SJohn Marino #else
18386d7f5d3SJohn Marino       if (CLEVER_CONDITION_1 ())
18486d7f5d3SJohn Marino 	{
18586d7f5d3SJohn Marino 	  /* perform adjustment operation of previous */
18686d7f5d3SJohn Marino 	  cy = mpn_mul_1 (p, p, n, big_base);
18786d7f5d3SJohn Marino 	}
18886d7f5d3SJohn Marino       if (CLEVER_CONDITION_2 ())
18986d7f5d3SJohn Marino 	{
19086d7f5d3SJohn Marino 	  /* perform adjustment operation of new */
19186d7f5d3SJohn Marino 	  cy = mpn_mul_1 (t, t, n, big_base);
19286d7f5d3SJohn Marino 	}
19386d7f5d3SJohn Marino #endif
19486d7f5d3SJohn Marino       shift *= 2;
19586d7f5d3SJohn Marino       /* Strip low zero limbs, but be careful to keep the result divisible by
19686d7f5d3SJohn Marino 	 big_base.  */
19786d7f5d3SJohn Marino       while (t[0] == 0 && (t[1] & ((big_base & -big_base) - 1)) == 0)
19886d7f5d3SJohn Marino 	{
19986d7f5d3SJohn Marino 	  t++;
20086d7f5d3SJohn Marino 	  n--;
20186d7f5d3SJohn Marino 	  shift++;
20286d7f5d3SJohn Marino 	}
20386d7f5d3SJohn Marino       p = t;
20486d7f5d3SJohn Marino       powtab[pi].p = p;
20586d7f5d3SJohn Marino       powtab[pi].n = n;
20686d7f5d3SJohn Marino       powtab[pi].digits_in_base = digits_in_base;
20786d7f5d3SJohn Marino       powtab[pi].base = base;
20886d7f5d3SJohn Marino       powtab[pi].shift = shift;
20986d7f5d3SJohn Marino     }
21086d7f5d3SJohn Marino }
21186d7f5d3SJohn Marino 
21286d7f5d3SJohn Marino mp_size_t
mpn_dc_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,const powers_t * powtab,mp_ptr tp)21386d7f5d3SJohn Marino mpn_dc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len,
21486d7f5d3SJohn Marino 		const powers_t *powtab, mp_ptr tp)
21586d7f5d3SJohn Marino {
21686d7f5d3SJohn Marino   size_t len_lo, len_hi;
21786d7f5d3SJohn Marino   mp_limb_t cy;
21886d7f5d3SJohn Marino   mp_size_t ln, hn, n, sn;
21986d7f5d3SJohn Marino 
22086d7f5d3SJohn Marino   len_lo = powtab->digits_in_base;
22186d7f5d3SJohn Marino 
22286d7f5d3SJohn Marino   if (str_len <= len_lo)
22386d7f5d3SJohn Marino     {
22486d7f5d3SJohn Marino       if (BELOW_THRESHOLD (str_len, SET_STR_DC_THRESHOLD))
22586d7f5d3SJohn Marino 	return mpn_bc_set_str (rp, str, str_len, powtab->base);
22686d7f5d3SJohn Marino       else
22786d7f5d3SJohn Marino 	return mpn_dc_set_str (rp, str, str_len, powtab + 1, tp);
22886d7f5d3SJohn Marino     }
22986d7f5d3SJohn Marino 
23086d7f5d3SJohn Marino   len_hi = str_len - len_lo;
23186d7f5d3SJohn Marino   ASSERT (len_lo >= len_hi);
23286d7f5d3SJohn Marino 
23386d7f5d3SJohn Marino   if (BELOW_THRESHOLD (len_hi, SET_STR_DC_THRESHOLD))
23486d7f5d3SJohn Marino     hn = mpn_bc_set_str (tp, str, len_hi, powtab->base);
23586d7f5d3SJohn Marino   else
23686d7f5d3SJohn Marino     hn = mpn_dc_set_str (tp, str, len_hi, powtab + 1, rp);
23786d7f5d3SJohn Marino 
23886d7f5d3SJohn Marino   sn = powtab->shift;
23986d7f5d3SJohn Marino 
24086d7f5d3SJohn Marino   if (hn == 0)
24186d7f5d3SJohn Marino     {
24286d7f5d3SJohn Marino       MPN_ZERO (rp, powtab->n + sn);
24386d7f5d3SJohn Marino     }
24486d7f5d3SJohn Marino   else
24586d7f5d3SJohn Marino     {
24686d7f5d3SJohn Marino       if (powtab->n > hn)
24786d7f5d3SJohn Marino 	mpn_mul (rp + sn, powtab->p, powtab->n, tp, hn);
24886d7f5d3SJohn Marino       else
24986d7f5d3SJohn Marino 	mpn_mul (rp + sn, tp, hn, powtab->p, powtab->n);
25086d7f5d3SJohn Marino       MPN_ZERO (rp, sn);
25186d7f5d3SJohn Marino     }
25286d7f5d3SJohn Marino 
25386d7f5d3SJohn Marino   str = str + str_len - len_lo;
25486d7f5d3SJohn Marino   if (BELOW_THRESHOLD (len_lo, SET_STR_DC_THRESHOLD))
25586d7f5d3SJohn Marino     ln = mpn_bc_set_str (tp, str, len_lo, powtab->base);
25686d7f5d3SJohn Marino   else
25786d7f5d3SJohn Marino     ln = mpn_dc_set_str (tp, str, len_lo, powtab + 1, tp + powtab->n + sn + 1);
25886d7f5d3SJohn Marino 
25986d7f5d3SJohn Marino   if (ln != 0)
26086d7f5d3SJohn Marino     {
26186d7f5d3SJohn Marino       cy = mpn_add_n (rp, rp, tp, ln);
26286d7f5d3SJohn Marino       mpn_incr_u (rp + ln, cy);
26386d7f5d3SJohn Marino     }
26486d7f5d3SJohn Marino   n = hn + powtab->n + sn;
26586d7f5d3SJohn Marino   return n - (rp[n - 1] == 0);
26686d7f5d3SJohn Marino }
26786d7f5d3SJohn Marino 
26886d7f5d3SJohn Marino mp_size_t
mpn_bc_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,int base)26986d7f5d3SJohn Marino mpn_bc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
27086d7f5d3SJohn Marino {
27186d7f5d3SJohn Marino   mp_size_t size;
27286d7f5d3SJohn Marino   size_t i;
27386d7f5d3SJohn Marino   long j;
27486d7f5d3SJohn Marino   mp_limb_t cy_limb;
27586d7f5d3SJohn Marino 
27686d7f5d3SJohn Marino   mp_limb_t big_base;
27786d7f5d3SJohn Marino   int chars_per_limb;
27886d7f5d3SJohn Marino   mp_limb_t res_digit;
27986d7f5d3SJohn Marino 
28086d7f5d3SJohn Marino   ASSERT (base >= 2);
28186d7f5d3SJohn Marino   ASSERT (base < numberof (mp_bases));
28286d7f5d3SJohn Marino   ASSERT (str_len >= 1);
28386d7f5d3SJohn Marino 
28486d7f5d3SJohn Marino   big_base = mp_bases[base].big_base;
28586d7f5d3SJohn Marino   chars_per_limb = mp_bases[base].chars_per_limb;
28686d7f5d3SJohn Marino 
28786d7f5d3SJohn Marino   size = 0;
28886d7f5d3SJohn Marino   for (i = chars_per_limb; i < str_len; i += chars_per_limb)
28986d7f5d3SJohn Marino     {
29086d7f5d3SJohn Marino       res_digit = *str++;
29186d7f5d3SJohn Marino       if (base == 10)
29286d7f5d3SJohn Marino 	{ /* This is a common case.
29386d7f5d3SJohn Marino 	     Help the compiler to avoid multiplication.  */
29486d7f5d3SJohn Marino 	  for (j = MP_BASES_CHARS_PER_LIMB_10 - 1; j != 0; j--)
29586d7f5d3SJohn Marino 	    res_digit = res_digit * 10 + *str++;
29686d7f5d3SJohn Marino 	}
29786d7f5d3SJohn Marino       else
29886d7f5d3SJohn Marino 	{
29986d7f5d3SJohn Marino 	  for (j = chars_per_limb - 1; j != 0; j--)
30086d7f5d3SJohn Marino 	    res_digit = res_digit * base + *str++;
30186d7f5d3SJohn Marino 	}
30286d7f5d3SJohn Marino 
30386d7f5d3SJohn Marino       if (size == 0)
30486d7f5d3SJohn Marino 	{
30586d7f5d3SJohn Marino 	  if (res_digit != 0)
30686d7f5d3SJohn Marino 	    {
30786d7f5d3SJohn Marino 	      rp[0] = res_digit;
30886d7f5d3SJohn Marino 	      size = 1;
30986d7f5d3SJohn Marino 	    }
31086d7f5d3SJohn Marino 	}
31186d7f5d3SJohn Marino       else
31286d7f5d3SJohn Marino 	{
31386d7f5d3SJohn Marino #if HAVE_NATIVE_mpn_mul_1c
31486d7f5d3SJohn Marino 	  cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
31586d7f5d3SJohn Marino #else
31686d7f5d3SJohn Marino 	  cy_limb = mpn_mul_1 (rp, rp, size, big_base);
31786d7f5d3SJohn Marino 	  cy_limb += mpn_add_1 (rp, rp, size, res_digit);
31886d7f5d3SJohn Marino #endif
31986d7f5d3SJohn Marino 	  if (cy_limb != 0)
32086d7f5d3SJohn Marino 	    rp[size++] = cy_limb;
32186d7f5d3SJohn Marino 	}
32286d7f5d3SJohn Marino     }
32386d7f5d3SJohn Marino 
32486d7f5d3SJohn Marino   big_base = base;
32586d7f5d3SJohn Marino   res_digit = *str++;
32686d7f5d3SJohn Marino   if (base == 10)
32786d7f5d3SJohn Marino     { /* This is a common case.
32886d7f5d3SJohn Marino 	 Help the compiler to avoid multiplication.  */
32986d7f5d3SJohn Marino       for (j = str_len - (i - MP_BASES_CHARS_PER_LIMB_10) - 1; j > 0; j--)
33086d7f5d3SJohn Marino 	{
33186d7f5d3SJohn Marino 	  res_digit = res_digit * 10 + *str++;
33286d7f5d3SJohn Marino 	  big_base *= 10;
33386d7f5d3SJohn Marino 	}
33486d7f5d3SJohn Marino     }
33586d7f5d3SJohn Marino   else
33686d7f5d3SJohn Marino     {
33786d7f5d3SJohn Marino       for (j = str_len - (i - chars_per_limb) - 1; j > 0; j--)
33886d7f5d3SJohn Marino 	{
33986d7f5d3SJohn Marino 	  res_digit = res_digit * base + *str++;
34086d7f5d3SJohn Marino 	  big_base *= base;
34186d7f5d3SJohn Marino 	}
34286d7f5d3SJohn Marino     }
34386d7f5d3SJohn Marino 
34486d7f5d3SJohn Marino   if (size == 0)
34586d7f5d3SJohn Marino     {
34686d7f5d3SJohn Marino       if (res_digit != 0)
34786d7f5d3SJohn Marino 	{
34886d7f5d3SJohn Marino 	  rp[0] = res_digit;
34986d7f5d3SJohn Marino 	  size = 1;
35086d7f5d3SJohn Marino 	}
35186d7f5d3SJohn Marino     }
35286d7f5d3SJohn Marino   else
35386d7f5d3SJohn Marino     {
35486d7f5d3SJohn Marino #if HAVE_NATIVE_mpn_mul_1c
35586d7f5d3SJohn Marino       cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
35686d7f5d3SJohn Marino #else
35786d7f5d3SJohn Marino       cy_limb = mpn_mul_1 (rp, rp, size, big_base);
35886d7f5d3SJohn Marino       cy_limb += mpn_add_1 (rp, rp, size, res_digit);
35986d7f5d3SJohn Marino #endif
36086d7f5d3SJohn Marino       if (cy_limb != 0)
36186d7f5d3SJohn Marino 	rp[size++] = cy_limb;
36286d7f5d3SJohn Marino     }
36386d7f5d3SJohn Marino   return size;
36486d7f5d3SJohn Marino }
365