refmpn.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:50k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Reference mpn functions, designed to be simple, portable and independent
  2.    of the normal gmp code.  Speed isn't a consideration.
  3. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
  4. 2007, 2008, 2009 Free Software Foundation, Inc.
  5. This file is part of the GNU MP Library.
  6. The GNU MP Library is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or (at your
  9. option) any later version.
  10. The GNU MP Library is distributed in the hope that it will be useful, but
  11. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  13. License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  16. /* Most routines have assertions representing what the mpn routines are
  17.    supposed to accept.  Many of these reference routines do sensible things
  18.    outside these ranges (eg. for size==0), but the assertions are present to
  19.    pick up bad parameters passed here that are about to be passed the same
  20.    to a real mpn routine being compared.  */
  21. /* always do assertion checking */
  22. #define WANT_ASSERT  1
  23. #include <stdio.h>  /* for NULL */
  24. #include <stdlib.h> /* for malloc */
  25. #include "gmp.h"
  26. #include "gmp-impl.h"
  27. #include "longlong.h"
  28. #include "tests.h"
  29. /* Return non-zero if regions {xp,xsize} and {yp,ysize} overlap, with sizes
  30.    in bytes. */
  31. int
  32. byte_overlap_p (const void *v_xp, mp_size_t xsize,
  33. const void *v_yp, mp_size_t ysize)
  34. {
  35.   const char *xp = v_xp;
  36.   const char *yp = v_yp;
  37.   ASSERT (xsize >= 0);
  38.   ASSERT (ysize >= 0);
  39.   /* no wraparounds */
  40.   ASSERT (xp+xsize >= xp);
  41.   ASSERT (yp+ysize >= yp);
  42.   if (xp + xsize <= yp)
  43.     return 0;
  44.   if (yp + ysize <= xp)
  45.     return 0;
  46.   return 1;
  47. }
  48. /* Return non-zero if limb regions {xp,xsize} and {yp,ysize} overlap. */
  49. int
  50. refmpn_overlap_p (mp_srcptr xp, mp_size_t xsize, mp_srcptr yp, mp_size_t ysize)
  51. {
  52.   return byte_overlap_p (xp, xsize * BYTES_PER_MP_LIMB,
  53.  yp, ysize * BYTES_PER_MP_LIMB);
  54. }
  55. /* Check overlap for a routine defined to work low to high. */
  56. int
  57. refmpn_overlap_low_to_high_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
  58. {
  59.   return (dst <= src || ! refmpn_overlap_p (dst, size, src, size));
  60. }
  61. /* Check overlap for a routine defined to work high to low. */
  62. int
  63. refmpn_overlap_high_to_low_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
  64. {
  65.   return (dst >= src || ! refmpn_overlap_p (dst, size, src, size));
  66. }
  67. /* Check overlap for a standard routine requiring equal or separate. */
  68. int
  69. refmpn_overlap_fullonly_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
  70. {
  71.   return (dst == src || ! refmpn_overlap_p (dst, size, src, size));
  72. }
  73. int
  74. refmpn_overlap_fullonly_two_p (mp_srcptr dst, mp_srcptr src1, mp_srcptr src2,
  75.        mp_size_t size)
  76. {
  77.   return (refmpn_overlap_fullonly_p (dst, src1, size)
  78.   && refmpn_overlap_fullonly_p (dst, src2, size));
  79. }
  80. mp_ptr
  81. refmpn_malloc_limbs (mp_size_t size)
  82. {
  83.   mp_ptr  p;
  84.   ASSERT (size >= 0);
  85.   if (size == 0)
  86.     size = 1;
  87.   p = (mp_ptr) malloc ((size_t) (size * BYTES_PER_MP_LIMB));
  88.   ASSERT (p != NULL);
  89.   return p;
  90. }
  91. /* Free limbs allocated by refmpn_malloc_limbs. NOTE: Can't free
  92.  * memory allocated by refmpn_malloc_limbs_aligned. */
  93. void
  94. refmpn_free_limbs (mp_ptr p)
  95. {
  96.   free (p);
  97. }
  98. mp_ptr
  99. refmpn_memdup_limbs (mp_srcptr ptr, mp_size_t size)
  100. {
  101.   mp_ptr  p;
  102.   p = refmpn_malloc_limbs (size);
  103.   refmpn_copyi (p, ptr, size);
  104.   return p;
  105. }
  106. /* malloc n limbs on a multiple of m bytes boundary */
  107. mp_ptr
  108. refmpn_malloc_limbs_aligned (mp_size_t n, size_t m)
  109. {
  110.   return (mp_ptr) align_pointer (refmpn_malloc_limbs (n + m-1), m);
  111. }
  112. void
  113. refmpn_fill (mp_ptr ptr, mp_size_t size, mp_limb_t value)
  114. {
  115.   mp_size_t  i;
  116.   ASSERT (size >= 0);
  117.   for (i = 0; i < size; i++)
  118.     ptr[i] = value;
  119. }
  120. void
  121. refmpn_zero (mp_ptr ptr, mp_size_t size)
  122. {
  123.   refmpn_fill (ptr, size, CNST_LIMB(0));
  124. }
  125. void
  126. refmpn_zero_extend (mp_ptr ptr, mp_size_t oldsize, mp_size_t newsize)
  127. {
  128.   ASSERT (newsize >= oldsize);
  129.   refmpn_zero (ptr+oldsize, newsize-oldsize);
  130. }
  131. int
  132. refmpn_zero_p (mp_srcptr ptr, mp_size_t size)
  133. {
  134.   mp_size_t  i;
  135.   for (i = 0; i < size; i++)
  136.     if (ptr[i] != 0)
  137.       return 0;
  138.   return 1;
  139. }
  140. mp_size_t
  141. refmpn_normalize (mp_srcptr ptr, mp_size_t size)
  142. {
  143.   ASSERT (size >= 0);
  144.   while (size > 0 && ptr[size-1] == 0)
  145.     size--;
  146.   return size;
  147. }
  148. /* the highest one bit in x */
  149. mp_limb_t
  150. refmpn_msbone (mp_limb_t x)
  151. {
  152.   mp_limb_t  n = (mp_limb_t) 1 << (GMP_LIMB_BITS-1);
  153.   while (n != 0)
  154.     {
  155.       if (x & n)
  156. break;
  157.       n >>= 1;
  158.     }
  159.   return n;
  160. }
  161. /* a mask of the highest one bit plus and all bits below */
  162. mp_limb_t
  163. refmpn_msbone_mask (mp_limb_t x)
  164. {
  165.   if (x == 0)
  166.     return 0;
  167.   return (refmpn_msbone (x) << 1) - 1;
  168. }
  169. /* How many digits in the given base will fit in a limb.
  170.    Notice that the product b is allowed to be equal to the limit
  171.    2^GMP_NUMB_BITS, this ensures the result for base==2 will be
  172.    GMP_NUMB_BITS (and similarly other powers of 2).  */
  173. int
  174. refmpn_chars_per_limb (int base)
  175. {
  176.   mp_limb_t  limit[2], b[2];
  177.   int        chars_per_limb;
  178.   ASSERT (base >= 2);
  179.   limit[0] = 0;  /* limit = 2^GMP_NUMB_BITS */
  180.   limit[1] = 1;
  181.   b[0] = 1;      /* b = 1 */
  182.   b[1] = 0;
  183.   chars_per_limb = 0;
  184.   for (;;)
  185.     {
  186.       if (refmpn_mul_1 (b, b, (mp_size_t) 2, (mp_limb_t) base))
  187. break;
  188.       if (refmpn_cmp (b, limit, (mp_size_t) 2) > 0)
  189. break;
  190.       chars_per_limb++;
  191.     }
  192.   return chars_per_limb;
  193. }
  194. /* The biggest value base**n which fits in GMP_NUMB_BITS. */
  195. mp_limb_t
  196. refmpn_big_base (int base)
  197. {
  198.   int        chars_per_limb = refmpn_chars_per_limb (base);
  199.   int        i;
  200.   mp_limb_t  bb;
  201.   ASSERT (base >= 2);
  202.   bb = 1;
  203.   for (i = 0; i < chars_per_limb; i++)
  204.     bb *= base;
  205.   return bb;
  206. }
  207. void
  208. refmpn_setbit (mp_ptr ptr, unsigned long bit)
  209. {
  210.   ptr[bit/GMP_NUMB_BITS] |= CNST_LIMB(1) << (bit%GMP_NUMB_BITS);
  211. }
  212. void
  213. refmpn_clrbit (mp_ptr ptr, unsigned long bit)
  214. {
  215.   ptr[bit/GMP_NUMB_BITS] &= ~ (CNST_LIMB(1) << (bit%GMP_NUMB_BITS));
  216. }
  217. #define REFMPN_TSTBIT(ptr,bit) 
  218.   (((ptr)[(bit)/GMP_NUMB_BITS] & (CNST_LIMB(1) << ((bit)%GMP_NUMB_BITS))) != 0)
  219. int
  220. refmpn_tstbit (mp_srcptr ptr, unsigned long bit)
  221. {
  222.   return REFMPN_TSTBIT (ptr, bit);
  223. }
  224. unsigned long
  225. refmpn_scan0 (mp_srcptr ptr, unsigned long bit)
  226. {
  227.   while (REFMPN_TSTBIT (ptr, bit) != 0)
  228.     bit++;
  229.   return bit;
  230. }
  231. unsigned long
  232. refmpn_scan1 (mp_srcptr ptr, unsigned long bit)
  233. {
  234.   while (REFMPN_TSTBIT (ptr, bit) == 0)
  235.     bit++;
  236.   return bit;
  237. }
  238. void
  239. refmpn_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  240. {
  241.   ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
  242.   refmpn_copyi (rp, sp, size);
  243. }
  244. void
  245. refmpn_copyi (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  246. {
  247.   mp_size_t i;
  248.   ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
  249.   ASSERT (size >= 0);
  250.   for (i = 0; i < size; i++)
  251.     rp[i] = sp[i];
  252. }
  253. void
  254. refmpn_copyd (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  255. {
  256.   mp_size_t i;
  257.   ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
  258.   ASSERT (size >= 0);
  259.   for (i = size-1; i >= 0; i--)
  260.     rp[i] = sp[i];
  261. }
  262. /* Copy {xp,xsize} to {wp,wsize}.  If x is shorter, then pad w with low
  263.    zeros to wsize.  If x is longer, then copy just the high wsize limbs.  */
  264. void
  265. refmpn_copy_extend (mp_ptr wp, mp_size_t wsize, mp_srcptr xp, mp_size_t xsize)
  266. {
  267.   ASSERT (wsize >= 0);
  268.   ASSERT (xsize >= 0);
  269.   /* high part of x if x bigger than w */
  270.   if (xsize > wsize)
  271.     {
  272.       xp += xsize - wsize;
  273.       xsize = wsize;
  274.     }
  275.   refmpn_copy (wp + wsize-xsize, xp, xsize);
  276.   refmpn_zero (wp, wsize-xsize);
  277. }
  278. int
  279. refmpn_cmp (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
  280. {
  281.   mp_size_t  i;
  282.   ASSERT (size >= 1);
  283.   ASSERT_MPN (xp, size);
  284.   ASSERT_MPN (yp, size);
  285.   for (i = size-1; i >= 0; i--)
  286.     {
  287.       if (xp[i] > yp[i])  return 1;
  288.       if (xp[i] < yp[i])  return -1;
  289.     }
  290.   return 0;
  291. }
  292. int
  293. refmpn_cmp_allowzero (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
  294. {
  295.   if (size == 0)
  296.     return 0;
  297.   else
  298.     return refmpn_cmp (xp, yp, size);
  299. }
  300. int
  301. refmpn_cmp_twosizes (mp_srcptr xp, mp_size_t xsize,
  302.      mp_srcptr yp, mp_size_t ysize)
  303. {
  304.   int  opp, cmp;
  305.   ASSERT_MPN (xp, xsize);
  306.   ASSERT_MPN (yp, ysize);
  307.   opp = (xsize < ysize);
  308.   if (opp)
  309.     MPN_SRCPTR_SWAP (xp,xsize, yp,ysize);
  310.   if (! refmpn_zero_p (xp+ysize, xsize-ysize))
  311.     cmp = 1;
  312.   else
  313.     cmp = refmpn_cmp (xp, yp, ysize);
  314.   return (opp ? -cmp : cmp);
  315. }
  316. int
  317. refmpn_equal_anynail (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
  318. {
  319.   mp_size_t  i;
  320.   ASSERT (size >= 0);
  321.   for (i = 0; i < size; i++)
  322.       if (xp[i] != yp[i])
  323. return 0;
  324.   return 1;
  325. }
  326. #define LOGOPS(operation)                                               
  327.   {                                                                     
  328.     mp_size_t  i;                                                       
  329.     ASSERT (refmpn_overlap_fullonly_two_p (rp, s1p, s2p, size));        
  330.     ASSERT (size >= 1);                                                 
  331.     ASSERT_MPN (s1p, size);                                             
  332.     ASSERT_MPN (s2p, size);                                             
  333.     for (i = 0; i < size; i++)                                          
  334.       rp[i] = operation;                                                
  335.   }
  336. void
  337. refmpn_and_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  338. {
  339.   LOGOPS (s1p[i] & s2p[i]);
  340. }
  341. void
  342. refmpn_andn_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  343. {
  344.   LOGOPS (s1p[i] & ~s2p[i]);
  345. }
  346. void
  347. refmpn_nand_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  348. {
  349.   LOGOPS ((s1p[i] & s2p[i]) ^ GMP_NUMB_MASK);
  350. }
  351. void
  352. refmpn_ior_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  353. {
  354.   LOGOPS (s1p[i] | s2p[i]);
  355. }
  356. void
  357. refmpn_iorn_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  358. {
  359.   LOGOPS (s1p[i] | (s2p[i] ^ GMP_NUMB_MASK));
  360. }
  361. void
  362. refmpn_nior_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  363. {
  364.   LOGOPS ((s1p[i] | s2p[i]) ^ GMP_NUMB_MASK);
  365. }
  366. void
  367. refmpn_xor_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  368. {
  369.   LOGOPS (s1p[i] ^ s2p[i]);
  370. }
  371. void
  372. refmpn_xnor_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  373. {
  374.   LOGOPS ((s1p[i] ^ s2p[i]) ^ GMP_NUMB_MASK);
  375. }
  376. /* set *dh,*dl to mh:ml - sh:sl, in full limbs */
  377. void
  378. refmpn_sub_ddmmss (mp_limb_t *dh, mp_limb_t *dl,
  379.    mp_limb_t mh, mp_limb_t ml, mp_limb_t sh, mp_limb_t sl)
  380. {
  381.   *dl = ml - sl;
  382.   *dh = mh - sh - (ml < sl);
  383. }
  384. /* set *w to x+y, return 0 or 1 carry */
  385. mp_limb_t
  386. ref_addc_limb (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
  387. {
  388.   mp_limb_t  sum, cy;
  389.   ASSERT_LIMB (x);
  390.   ASSERT_LIMB (y);
  391.   sum = x + y;
  392. #if GMP_NAIL_BITS == 0
  393.   *w = sum;
  394.   cy = (sum < x);
  395. #else
  396.   *w = sum & GMP_NUMB_MASK;
  397.   cy = (sum >> GMP_NUMB_BITS);
  398. #endif
  399.   return cy;
  400. }
  401. /* set *w to x-y, return 0 or 1 borrow */
  402. mp_limb_t
  403. ref_subc_limb (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
  404. {
  405.   mp_limb_t  diff, cy;
  406.   ASSERT_LIMB (x);
  407.   ASSERT_LIMB (y);
  408.   diff = x - y;
  409. #if GMP_NAIL_BITS == 0
  410.   *w = diff;
  411.   cy = (diff > x);
  412. #else
  413.   *w = diff & GMP_NUMB_MASK;
  414.   cy = (diff >> GMP_NUMB_BITS) & 1;
  415. #endif
  416.   return cy;
  417. }
  418. /* set *w to x+y+c (where c is 0 or 1), return 0 or 1 carry */
  419. mp_limb_t
  420. adc (mp_limb_t *w, mp_limb_t x, mp_limb_t y, mp_limb_t c)
  421. {
  422.   mp_limb_t  r;
  423.   ASSERT_LIMB (x);
  424.   ASSERT_LIMB (y);
  425.   ASSERT (c == 0 || c == 1);
  426.   r = ref_addc_limb (w, x, y);
  427.   return r + ref_addc_limb (w, *w, c);
  428. }
  429. /* set *w to x-y-c (where c is 0 or 1), return 0 or 1 borrow */
  430. mp_limb_t
  431. sbb (mp_limb_t *w, mp_limb_t x, mp_limb_t y, mp_limb_t c)
  432. {
  433.   mp_limb_t  r;
  434.   ASSERT_LIMB (x);
  435.   ASSERT_LIMB (y);
  436.   ASSERT (c == 0 || c == 1);
  437.   r = ref_subc_limb (w, x, y);
  438.   return r + ref_subc_limb (w, *w, c);
  439. }
  440. #define AORS_1(operation)                               
  441.   {                                                     
  442.     mp_limb_t  i;                                       
  443.     ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));  
  444.     ASSERT (size >= 1);                                 
  445.     ASSERT_MPN (sp, size);                              
  446.     ASSERT_LIMB (n);                                    
  447.     for (i = 0; i < size; i++)                          
  448.       n = operation (&rp[i], sp[i], n);                 
  449.     return n;                                           
  450.   }
  451. mp_limb_t
  452. refmpn_add_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t n)
  453. {
  454.   AORS_1 (ref_addc_limb);
  455. }
  456. mp_limb_t
  457. refmpn_sub_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t n)
  458. {
  459.   AORS_1 (ref_subc_limb);
  460. }
  461. #define AORS_NC(operation)                                              
  462.   {                                                                     
  463.     mp_size_t  i;                                                       
  464.     ASSERT (refmpn_overlap_fullonly_two_p (rp, s1p, s2p, size));        
  465.     ASSERT (carry == 0 || carry == 1);                                  
  466.     ASSERT (size >= 1);                                                 
  467.     ASSERT_MPN (s1p, size);                                             
  468.     ASSERT_MPN (s2p, size);                                             
  469.     for (i = 0; i < size; i++)                                          
  470.       carry = operation (&rp[i], s1p[i], s2p[i], carry);                
  471.     return carry;                                                       
  472.   }
  473. mp_limb_t
  474. refmpn_add_nc (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
  475.        mp_limb_t carry)
  476. {
  477.   AORS_NC (adc);
  478. }
  479. mp_limb_t
  480. refmpn_sub_nc (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
  481.        mp_limb_t carry)
  482. {
  483.   AORS_NC (sbb);
  484. }
  485. mp_limb_t
  486. refmpn_add_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  487. {
  488.   return refmpn_add_nc (rp, s1p, s2p, size, CNST_LIMB(0));
  489. }
  490. mp_limb_t
  491. refmpn_sub_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  492. {
  493.   return refmpn_sub_nc (rp, s1p, s2p, size, CNST_LIMB(0));
  494. }
  495. mp_limb_t
  496. refmpn_addlsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
  497.  mp_size_t n, unsigned int s)
  498. {
  499.   mp_limb_t cy;
  500.   mp_ptr tp;
  501.   ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
  502.   ASSERT (n >= 1);
  503.   ASSERT (0 < s && s < GMP_NUMB_BITS);
  504.   ASSERT_MPN (up, n);
  505.   ASSERT_MPN (vp, n);
  506.   tp = refmpn_malloc_limbs (n);
  507.   cy  = refmpn_lshift (tp, vp, n, s);
  508.   cy += refmpn_add_n (rp, up, tp, n);
  509.   free (tp);
  510.   return cy;
  511. }
  512. mp_limb_t
  513. refmpn_addlsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  514. {
  515.   return refmpn_addlsh_n (rp, up, vp, n, 1);
  516. }
  517. mp_limb_t
  518. refmpn_addlsh2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  519. {
  520.   return refmpn_addlsh_n (rp, up, vp, n, 2);
  521. }
  522. mp_limb_t
  523. refmpn_sublsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
  524.  mp_size_t n, unsigned int s)
  525. {
  526.   mp_limb_t cy;
  527.   mp_ptr tp;
  528.   ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
  529.   ASSERT (n >= 1);
  530.   ASSERT (0 < s && s < GMP_NUMB_BITS);
  531.   ASSERT_MPN (up, n);
  532.   ASSERT_MPN (vp, n);
  533.   tp = refmpn_malloc_limbs (n);
  534.   cy  = mpn_lshift (tp, vp, n, s);
  535.   cy += mpn_sub_n (rp, up, tp, n);
  536.   free (tp);
  537.   return cy;
  538. }
  539. mp_limb_t
  540. refmpn_sublsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  541. {
  542.   return refmpn_sublsh_n (rp, up, vp, n, 1);
  543. }
  544. mp_limb_signed_t
  545. refmpn_rsblsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
  546.  mp_size_t n, unsigned int s)
  547. {
  548.   mp_limb_signed_t cy;
  549.   mp_ptr tp;
  550.   ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
  551.   ASSERT (n >= 1);
  552.   ASSERT (0 < s && s < GMP_NUMB_BITS);
  553.   ASSERT_MPN (up, n);
  554.   ASSERT_MPN (vp, n);
  555.   tp = refmpn_malloc_limbs (n);
  556.   cy  = mpn_lshift (tp, vp, n, s);
  557.   cy -= mpn_sub_n (rp, tp, up, n);
  558.   free (tp);
  559.   return cy;
  560. }
  561. mp_limb_signed_t
  562. refmpn_rsblsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  563. {
  564.   return refmpn_rsblsh_n (rp, up, vp, n, 1);
  565. }
  566. mp_limb_signed_t
  567. refmpn_rsblsh2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  568. {
  569.   return refmpn_rsblsh_n (rp, up, vp, n, 2);
  570. }
  571. mp_limb_t
  572. refmpn_rsh1add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  573. {
  574.   mp_limb_t cya, cys;
  575.   ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
  576.   ASSERT (n >= 1);
  577.   ASSERT_MPN (up, n);
  578.   ASSERT_MPN (vp, n);
  579.   cya = mpn_add_n (rp, up, vp, n);
  580.   cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
  581.   rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
  582.   return cys;
  583. }
  584. mp_limb_t
  585. refmpn_rsh1sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  586. {
  587.   mp_limb_t cya, cys;
  588.   ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
  589.   ASSERT (n >= 1);
  590.   ASSERT_MPN (up, n);
  591.   ASSERT_MPN (vp, n);
  592.   cya = mpn_sub_n (rp, up, vp, n);
  593.   cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
  594.   rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
  595.   return cys;
  596. }
  597. /* Twos complement, return borrow. */
  598. mp_limb_t
  599. refmpn_neg (mp_ptr dst, mp_srcptr src, mp_size_t size)
  600. {
  601.   mp_ptr     zeros;
  602.   mp_limb_t  ret;
  603.   ASSERT (size >= 1);
  604.   zeros = refmpn_malloc_limbs (size);
  605.   refmpn_fill (zeros, size, CNST_LIMB(0));
  606.   ret = refmpn_sub_n (dst, zeros, src, size);
  607.   free (zeros);
  608.   return ret;
  609. }
  610. #define AORS(aors_n, aors_1)                                    
  611.   {                                                             
  612.     mp_limb_t  c;                                               
  613.     ASSERT (s1size >= s2size);                                  
  614.     ASSERT (s2size >= 1);                                       
  615.     c = aors_n (rp, s1p, s2p, s2size);                          
  616.     if (s1size-s2size != 0)                                     
  617.       c = aors_1 (rp+s2size, s1p+s2size, s1size-s2size, c);     
  618.     return c;                                                   
  619.   }
  620. mp_limb_t
  621. refmpn_add (mp_ptr rp,
  622.     mp_srcptr s1p, mp_size_t s1size,
  623.     mp_srcptr s2p, mp_size_t s2size)
  624. {
  625.   AORS (refmpn_add_n, refmpn_add_1);
  626. }
  627. mp_limb_t
  628. refmpn_sub (mp_ptr rp,
  629.     mp_srcptr s1p, mp_size_t s1size,
  630.     mp_srcptr s2p, mp_size_t s2size)
  631. {
  632.   AORS (refmpn_sub_n, refmpn_sub_1);
  633. }
  634. #define SHIFTHIGH(x) ((x) << GMP_LIMB_BITS/2)
  635. #define SHIFTLOW(x)  ((x) >> GMP_LIMB_BITS/2)
  636. #define LOWMASK   (((mp_limb_t) 1 << GMP_LIMB_BITS/2)-1)
  637. #define HIGHMASK  SHIFTHIGH(LOWMASK)
  638. #define LOWPART(x)   ((x) & LOWMASK)
  639. #define HIGHPART(x)  SHIFTLOW((x) & HIGHMASK)
  640. /* Set return:*lo to x*y, using full limbs not nails. */
  641. mp_limb_t
  642. refmpn_umul_ppmm (mp_limb_t *lo, mp_limb_t x, mp_limb_t y)
  643. {
  644.   mp_limb_t  hi, s;
  645.   *lo = LOWPART(x) * LOWPART(y);
  646.   hi = HIGHPART(x) * HIGHPART(y);
  647.   s = LOWPART(x) * HIGHPART(y);
  648.   hi += HIGHPART(s);
  649.   s = SHIFTHIGH(LOWPART(s));
  650.   *lo += s;
  651.   hi += (*lo < s);
  652.   s = HIGHPART(x) * LOWPART(y);
  653.   hi += HIGHPART(s);
  654.   s = SHIFTHIGH(LOWPART(s));
  655.   *lo += s;
  656.   hi += (*lo < s);
  657.   return hi;
  658. }
  659. mp_limb_t
  660. refmpn_umul_ppmm_r (mp_limb_t x, mp_limb_t y, mp_limb_t *lo)
  661. {
  662.   return refmpn_umul_ppmm (lo, x, y);
  663. }
  664. mp_limb_t
  665. refmpn_mul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier,
  666.        mp_limb_t carry)
  667. {
  668.   mp_size_t  i;
  669.   mp_limb_t  hi, lo;
  670.   ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
  671.   ASSERT (size >= 1);
  672.   ASSERT_MPN (sp, size);
  673.   ASSERT_LIMB (multiplier);
  674.   ASSERT_LIMB (carry);
  675.   multiplier <<= GMP_NAIL_BITS;
  676.   for (i = 0; i < size; i++)
  677.     {
  678.       hi = refmpn_umul_ppmm (&lo, sp[i], multiplier);
  679.       lo >>= GMP_NAIL_BITS;
  680.       ASSERT_NOCARRY (ref_addc_limb (&hi, hi, ref_addc_limb (&lo, lo, carry)));
  681.       rp[i] = lo;
  682.       carry = hi;
  683.     }
  684.   return carry;
  685. }
  686. mp_limb_t
  687. refmpn_mul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
  688. {
  689.   return refmpn_mul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
  690. }
  691. mp_limb_t
  692. refmpn_mul_N (mp_ptr dst, mp_srcptr src, mp_size_t size,
  693.       mp_srcptr mult, mp_size_t msize)
  694. {
  695.   mp_ptr     src_copy;
  696.   mp_limb_t  ret;
  697.   mp_size_t  i;
  698.   ASSERT (refmpn_overlap_fullonly_p (dst, src, size));
  699.   ASSERT (! refmpn_overlap_p (dst, size+msize-1, mult, msize));
  700.   ASSERT (size >= msize);
  701.   ASSERT_MPN (mult, msize);
  702.   /* in case dst==src */
  703.   src_copy = refmpn_malloc_limbs (size);
  704.   refmpn_copyi (src_copy, src, size);
  705.   src = src_copy;
  706.   dst[size] = refmpn_mul_1 (dst, src, size, mult[0]);
  707.   for (i = 1; i < msize-1; i++)
  708.     dst[size+i] = refmpn_addmul_1 (dst+i, src, size, mult[i]);
  709.   ret = refmpn_addmul_1 (dst+i, src, size, mult[i]);
  710.   free (src_copy);
  711.   return ret;
  712. }
  713. mp_limb_t
  714. refmpn_mul_2 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  715. {
  716.   return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 2);
  717. }
  718. mp_limb_t
  719. refmpn_mul_3 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  720. {
  721.   return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 3);
  722. }
  723. mp_limb_t
  724. refmpn_mul_4 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  725. {
  726.   return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 4);
  727. }
  728. #define AORSMUL_1C(operation_n)                                 
  729.   {                                                             
  730.     mp_ptr     p;                                               
  731.     mp_limb_t  ret;                                             
  732.     ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));          
  733.     p = refmpn_malloc_limbs (size);                             
  734.     ret = refmpn_mul_1c (p, sp, size, multiplier, carry);       
  735.     ret += operation_n (rp, rp, p, size);                       
  736.     free (p);                                                   
  737.     return ret;                                                 
  738.   }
  739. mp_limb_t
  740. refmpn_addmul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  741.   mp_limb_t multiplier, mp_limb_t carry)
  742. {
  743.   AORSMUL_1C (refmpn_add_n);
  744. }
  745. mp_limb_t
  746. refmpn_submul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  747.   mp_limb_t multiplier, mp_limb_t carry)
  748. {
  749.   AORSMUL_1C (refmpn_sub_n);
  750. }
  751. mp_limb_t
  752. refmpn_addmul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
  753. {
  754.   return refmpn_addmul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
  755. }
  756. mp_limb_t
  757. refmpn_submul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
  758. {
  759.   return refmpn_submul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
  760. }
  761. mp_limb_t
  762. refmpn_addmul_N (mp_ptr dst, mp_srcptr src, mp_size_t size,
  763.  mp_srcptr mult, mp_size_t msize)
  764. {
  765.   mp_ptr     src_copy;
  766.   mp_limb_t  ret;
  767.   mp_size_t  i;
  768.   ASSERT (dst == src || ! refmpn_overlap_p (dst, size+msize-1, src, size));
  769.   ASSERT (! refmpn_overlap_p (dst, size+msize-1, mult, msize));
  770.   ASSERT (size >= msize);
  771.   ASSERT_MPN (mult, msize);
  772.   /* in case dst==src */
  773.   src_copy = refmpn_malloc_limbs (size);
  774.   refmpn_copyi (src_copy, src, size);
  775.   src = src_copy;
  776.   for (i = 0; i < msize-1; i++)
  777.     dst[size+i] = refmpn_addmul_1 (dst+i, src, size, mult[i]);
  778.   ret = refmpn_addmul_1 (dst+i, src, size, mult[i]);
  779.   free (src_copy);
  780.   return ret;
  781. }
  782. mp_limb_t
  783. refmpn_addmul_2 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  784. {
  785.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 2);
  786. }
  787. mp_limb_t
  788. refmpn_addmul_3 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  789. {
  790.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 3);
  791. }
  792. mp_limb_t
  793. refmpn_addmul_4 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  794. {
  795.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 4);
  796. }
  797. mp_limb_t
  798. refmpn_addmul_5 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  799. {
  800.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 5);
  801. }
  802. mp_limb_t
  803. refmpn_addmul_6 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  804. {
  805.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 6);
  806. }
  807. mp_limb_t
  808. refmpn_addmul_7 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  809. {
  810.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 7);
  811. }
  812. mp_limb_t
  813. refmpn_addmul_8 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
  814. {
  815.   return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 8);
  816. }
  817. mp_limb_t
  818. refmpn_add_n_sub_nc (mp_ptr r1p, mp_ptr r2p,
  819.   mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
  820.   mp_limb_t carry)
  821. {
  822.   mp_ptr p;
  823.   mp_limb_t acy, scy;
  824.   /* Destinations can't overlap. */
  825.   ASSERT (! refmpn_overlap_p (r1p, size, r2p, size));
  826.   ASSERT (refmpn_overlap_fullonly_two_p (r1p, s1p, s2p, size));
  827.   ASSERT (refmpn_overlap_fullonly_two_p (r2p, s1p, s2p, size));
  828.   ASSERT (size >= 1);
  829.   /* in case r1p==s1p or r1p==s2p */
  830.   p = refmpn_malloc_limbs (size);
  831.   acy = refmpn_add_nc (p, s1p, s2p, size, carry >> 1);
  832.   scy = refmpn_sub_nc (r2p, s1p, s2p, size, carry & 1);
  833.   refmpn_copyi (r1p, p, size);
  834.   free (p);
  835.   return 2 * acy + scy;
  836. }
  837. mp_limb_t
  838. refmpn_add_n_sub_n (mp_ptr r1p, mp_ptr r2p,
  839.  mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  840. {
  841.   return refmpn_add_n_sub_nc (r1p, r2p, s1p, s2p, size, CNST_LIMB(0));
  842. }
  843. /* Right shift hi,lo and return the low limb of the result.
  844.    Note a shift by GMP_LIMB_BITS isn't assumed to work (doesn't on x86). */
  845. mp_limb_t
  846. rshift_make (mp_limb_t hi, mp_limb_t lo, unsigned shift)
  847. {
  848.   ASSERT (shift < GMP_NUMB_BITS);
  849.   if (shift == 0)
  850.     return lo;
  851.   else
  852.     return ((hi << (GMP_NUMB_BITS-shift)) | (lo >> shift)) & GMP_NUMB_MASK;
  853. }
  854. /* Left shift hi,lo and return the high limb of the result.
  855.    Note a shift by GMP_LIMB_BITS isn't assumed to work (doesn't on x86). */
  856. mp_limb_t
  857. lshift_make (mp_limb_t hi, mp_limb_t lo, unsigned shift)
  858. {
  859.   ASSERT (shift < GMP_NUMB_BITS);
  860.   if (shift == 0)
  861.     return hi;
  862.   else
  863.     return ((hi << shift) | (lo >> (GMP_NUMB_BITS-shift))) & GMP_NUMB_MASK;
  864. }
  865. mp_limb_t
  866. refmpn_rshift (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
  867. {
  868.   mp_limb_t  ret;
  869.   mp_size_t  i;
  870.   ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
  871.   ASSERT (size >= 1);
  872.   ASSERT (shift >= 1 && shift < GMP_NUMB_BITS);
  873.   ASSERT_MPN (sp, size);
  874.   ret = rshift_make (sp[0], CNST_LIMB(0), shift);
  875.   for (i = 0; i < size-1; i++)
  876.     rp[i] = rshift_make (sp[i+1], sp[i], shift);
  877.   rp[i] = rshift_make (CNST_LIMB(0), sp[i], shift);
  878.   return ret;
  879. }
  880. mp_limb_t
  881. refmpn_lshift (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
  882. {
  883.   mp_limb_t  ret;
  884.   mp_size_t  i;
  885.   ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
  886.   ASSERT (size >= 1);
  887.   ASSERT (shift >= 1 && shift < GMP_NUMB_BITS);
  888.   ASSERT_MPN (sp, size);
  889.   ret = lshift_make (CNST_LIMB(0), sp[size-1], shift);
  890.   for (i = size-2; i >= 0; i--)
  891.     rp[i+1] = lshift_make (sp[i+1], sp[i], shift);
  892.   rp[i+1] = lshift_make (sp[i+1], CNST_LIMB(0), shift);
  893.   return ret;
  894. }
  895. void
  896. refmpn_com (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  897. {
  898.   mp_size_t i;
  899.   /* We work downwards since mpn_lshiftc needs that. */
  900.   ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
  901.   for (i = size - 1; i >= 0; i--)
  902.     rp[i] = (~sp[i]) & GMP_NUMB_MASK;
  903. }
  904. mp_limb_t
  905. refmpn_lshiftc (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
  906. {
  907.   mp_limb_t res;
  908.   /* No asserts here, refmpn_lshift will assert what we need. */
  909.   res = refmpn_lshift (rp, sp, size, shift);
  910.   refmpn_com (rp, rp, size);
  911.   return res;
  912. }
  913. /* accepting shift==0 and doing a plain copyi or copyd in that case */
  914. mp_limb_t
  915. refmpn_rshift_or_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
  916. {
  917.   if (shift == 0)
  918.     {
  919.       refmpn_copyi (rp, sp, size);
  920.       return 0;
  921.     }
  922.   else
  923.     {
  924.       return refmpn_rshift (rp, sp, size, shift);
  925.     }
  926. }
  927. mp_limb_t
  928. refmpn_lshift_or_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
  929. {
  930.   if (shift == 0)
  931.     {
  932.       refmpn_copyd (rp, sp, size);
  933.       return 0;
  934.     }
  935.   else
  936.     {
  937.       return refmpn_lshift (rp, sp, size, shift);
  938.     }
  939. }
  940. /* accepting size==0 too */
  941. mp_limb_t
  942. refmpn_rshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  943.    unsigned shift)
  944. {
  945.   return (size == 0 ? 0 : refmpn_rshift_or_copy (rp, sp, size, shift));
  946. }
  947. mp_limb_t
  948. refmpn_lshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  949.    unsigned shift)
  950. {
  951.   return (size == 0 ? 0 : refmpn_lshift_or_copy (rp, sp, size, shift));
  952. }
  953. /* Divide h,l by d, return quotient, store remainder to *rp.
  954.    Operates on full limbs, not nails.
  955.    Must have h < d.
  956.    __udiv_qrnnd_c isn't simple, and it's a bit slow, but it works. */
  957. mp_limb_t
  958. refmpn_udiv_qrnnd (mp_limb_t *rp, mp_limb_t h, mp_limb_t l, mp_limb_t d)
  959. {
  960.   mp_limb_t  q, r;
  961.   int  n;
  962.   ASSERT (d != 0);
  963.   ASSERT (h < d);
  964. #if 0
  965.   udiv_qrnnd (q, r, h, l, d);
  966.   *rp = r;
  967.   return q;
  968. #endif
  969.   n = refmpn_count_leading_zeros (d);
  970.   d <<= n;
  971.   if (n != 0)
  972.     {
  973.       h = (h << n) | (l >> (GMP_LIMB_BITS - n));
  974.       l <<= n;
  975.     }
  976.   __udiv_qrnnd_c (q, r, h, l, d);
  977.   r >>= n;
  978.   *rp = r;
  979.   return q;
  980. }
  981. mp_limb_t
  982. refmpn_udiv_qrnnd_r (mp_limb_t h, mp_limb_t l, mp_limb_t d, mp_limb_t *rp)
  983. {
  984.   return refmpn_udiv_qrnnd (rp, h, l, d);
  985. }
  986. /* This little subroutine avoids some bad code generation from i386 gcc 3.0
  987.    -fPIC -O2 -fomit-frame-pointer (%ebp being used uninitialized).  */
  988. static mp_limb_t
  989. refmpn_divmod_1c_workaround (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  990.      mp_limb_t divisor, mp_limb_t carry)
  991. {
  992.   mp_size_t  i;
  993.   mp_limb_t rem[1];
  994.   for (i = size-1; i >= 0; i--)
  995.     {
  996.       rp[i] = refmpn_udiv_qrnnd (rem, carry,
  997.  sp[i] << GMP_NAIL_BITS,
  998.  divisor << GMP_NAIL_BITS);
  999.       carry = *rem >> GMP_NAIL_BITS;
  1000.     }
  1001.   return carry;
  1002. }
  1003. mp_limb_t
  1004. refmpn_divmod_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
  1005.   mp_limb_t divisor, mp_limb_t carry)
  1006. {
  1007.   mp_ptr     sp_orig;
  1008.   mp_ptr     prod;
  1009.   mp_limb_t  carry_orig;
  1010.   ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
  1011.   ASSERT (size >= 0);
  1012.   ASSERT (carry < divisor);
  1013.   ASSERT_MPN (sp, size);
  1014.   ASSERT_LIMB (divisor);
  1015.   ASSERT_LIMB (carry);
  1016.   if (size == 0)
  1017.     return carry;
  1018.   sp_orig = refmpn_memdup_limbs (sp, size);
  1019.   prod = refmpn_malloc_limbs (size);
  1020.   carry_orig = carry;
  1021.   carry = refmpn_divmod_1c_workaround (rp, sp, size, divisor, carry);
  1022.   /* check by multiplying back */
  1023. #if 0
  1024.   printf ("size=%ld divisor=0x%lX carry=0x%lX remainder=0x%lXn",
  1025.   size, divisor, carry_orig, carry);
  1026.   mpn_trace("s",sp_copy,size);
  1027.   mpn_trace("r",rp,size);
  1028.   printf ("mul_1c %lXn", refmpn_mul_1c (prod, rp, size, divisor, carry));
  1029.   mpn_trace("p",prod,size);
  1030. #endif
  1031.   ASSERT (refmpn_mul_1c (prod, rp, size, divisor, carry) == carry_orig);
  1032.   ASSERT (refmpn_cmp (prod, sp_orig, size) == 0);
  1033.   free (sp_orig);
  1034.   free (prod);
  1035.   return carry;
  1036. }
  1037. mp_limb_t
  1038. refmpn_divmod_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
  1039. {
  1040.   return refmpn_divmod_1c (rp, sp, size, divisor, CNST_LIMB(0));
  1041. }
  1042. mp_limb_t
  1043. refmpn_mod_1c (mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
  1044.        mp_limb_t carry)
  1045. {
  1046.   mp_ptr  p = refmpn_malloc_limbs (size);
  1047.   carry = refmpn_divmod_1c (p, sp, size, divisor, carry);
  1048.   free (p);
  1049.   return carry;
  1050. }
  1051. mp_limb_t
  1052. refmpn_mod_1 (mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
  1053. {
  1054.   return refmpn_mod_1c (sp, size, divisor, CNST_LIMB(0));
  1055. }
  1056. mp_limb_t
  1057. refmpn_preinv_mod_1 (mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
  1058.      mp_limb_t inverse)
  1059. {
  1060.   ASSERT (divisor & GMP_NUMB_HIGHBIT);
  1061.   ASSERT (inverse == refmpn_invert_limb (divisor));
  1062.   return refmpn_mod_1 (sp, size, divisor);
  1063. }
  1064. /* This implementation will be rather slow, but has the advantage of being
  1065.    in a different style than the libgmp versions.  */
  1066. mp_limb_t
  1067. refmpn_mod_34lsub1 (mp_srcptr p, mp_size_t n)
  1068. {
  1069.   ASSERT ((GMP_NUMB_BITS % 4) == 0);
  1070.   return mpn_mod_1 (p, n, (CNST_LIMB(1) << (3 * GMP_NUMB_BITS / 4)) - 1);
  1071. }
  1072. mp_limb_t
  1073. refmpn_divrem_1c (mp_ptr rp, mp_size_t xsize,
  1074.   mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
  1075.   mp_limb_t carry)
  1076. {
  1077.   mp_ptr  z;
  1078.   z = refmpn_malloc_limbs (xsize);
  1079.   refmpn_fill (z, xsize, CNST_LIMB(0));
  1080.   carry = refmpn_divmod_1c (rp+xsize, sp, size, divisor, carry);
  1081.   carry = refmpn_divmod_1c (rp, z, xsize, divisor, carry);
  1082.   free (z);
  1083.   return carry;
  1084. }
  1085. mp_limb_t
  1086. refmpn_divrem_1 (mp_ptr rp, mp_size_t xsize,
  1087.  mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
  1088. {
  1089.   return refmpn_divrem_1c (rp, xsize, sp, size, divisor, CNST_LIMB(0));
  1090. }
  1091. mp_limb_t
  1092. refmpn_preinv_divrem_1 (mp_ptr rp, mp_size_t xsize,
  1093. mp_srcptr sp, mp_size_t size,
  1094. mp_limb_t divisor, mp_limb_t inverse, unsigned shift)
  1095. {
  1096.   ASSERT (size >= 0);
  1097.   ASSERT (shift == refmpn_count_leading_zeros (divisor));
  1098.   ASSERT (inverse == refmpn_invert_limb (divisor << shift));
  1099.   return refmpn_divrem_1 (rp, xsize, sp, size, divisor);
  1100. }
  1101. mp_limb_t
  1102. refmpn_divrem_2 (mp_ptr qp, mp_size_t qxn,
  1103.  mp_ptr np, mp_size_t nn,
  1104.  mp_srcptr dp)
  1105. {
  1106.   mp_ptr tp;
  1107.   mp_limb_t qh;
  1108.   tp = refmpn_malloc_limbs (nn + qxn);
  1109.   refmpn_zero (tp, qxn);
  1110.   refmpn_copyi (tp + qxn, np, nn);
  1111.   qh = refmpn_sb_div_qr (qp, tp, nn + qxn, dp, 2);
  1112.   refmpn_copyi (np, tp, 2);
  1113.   free (tp);
  1114.   return qh;
  1115. }
  1116. /* Inverse is floor((b*(b-d)-1) / d), per division by invariant integers
  1117.    paper, figure 8.1 m', where b=2^GMP_LIMB_BITS.  Note that -d-1 < d
  1118.    since d has the high bit set. */
  1119. mp_limb_t
  1120. refmpn_invert_limb (mp_limb_t d)
  1121. {
  1122.   mp_limb_t r;
  1123.   ASSERT (d & GMP_LIMB_HIGHBIT);
  1124.   return refmpn_udiv_qrnnd (&r, -d-1, MP_LIMB_T_MAX, d);
  1125. }
  1126. void
  1127. refmpn_invert (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr scratch)
  1128. {
  1129.   mp_ptr qp, tp;
  1130.   TMP_DECL;
  1131.   TMP_MARK;
  1132.   tp = TMP_ALLOC_LIMBS (2 * n);
  1133.   qp = TMP_ALLOC_LIMBS (n + 1);
  1134.   MPN_ZERO (tp, 2 * n);  mpn_sub_1 (tp, tp, 2 * n, 1);
  1135.   refmpn_tdiv_qr (qp, rp, 0, tp, 2 * n, up, n);
  1136.   refmpn_copyi (rp, qp, n);
  1137.   TMP_FREE;
  1138. }
  1139. void
  1140. refmpn_binvert (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr scratch)
  1141. {
  1142.   mp_ptr tp;
  1143.   mp_limb_t binv;
  1144.   TMP_DECL;
  1145.   TMP_MARK;
  1146.   /* We use the library mpn_sbpi1_bdiv_q here, which isn't kosher in testing
  1147.      code.  To make up for it, we check that the inverse is correct using a
  1148.      multiply.  */
  1149.   tp = TMP_ALLOC_LIMBS (2 * n);
  1150.   MPN_ZERO (tp, n);
  1151.   tp[0] = 1;
  1152.   binvert_limb (binv, up[0]);
  1153.   mpn_sbpi1_bdiv_q (rp, tp, n, up, n, -binv);
  1154.   refmpn_mul_n (tp, rp, up, n);
  1155.   ASSERT_ALWAYS (tp[0] == 1 && mpn_zero_p (tp + 1, n - 1));
  1156.   TMP_FREE;
  1157. }
  1158. /* The aim is to produce a dst quotient and return a remainder c, satisfying
  1159.    c*b^n + src-i == 3*dst, where i is the incoming carry.
  1160.    Some value c==0, c==1 or c==2 will satisfy, so just try each.
  1161.    If GMP_NUMB_BITS is even then 2^GMP_NUMB_BITS==1mod3 and a non-zero
  1162.    remainder from the first division attempt determines the correct
  1163.    remainder (3-c), but don't bother with that, since we can't guarantee
  1164.    anything about GMP_NUMB_BITS when using nails.
  1165.    If the initial src-i produces a borrow then refmpn_sub_1 leaves a twos
  1166.    complement negative, ie. b^n+a-i, and the calculation produces c1
  1167.    satisfying c1*b^n + b^n+src-i == 3*dst, from which clearly c=c1+1.  This
  1168.    means it's enough to just add any borrow back at the end.
  1169.    A borrow only occurs when a==0 or a==1, and, by the same reasoning as in
  1170.    mpn/generic/diveby3.c, the c1 that results in those cases will only be 0
  1171.    or 1 respectively, so with 1 added the final return value is still in the
  1172.    prescribed range 0 to 2. */
  1173. mp_limb_t
  1174. refmpn_divexact_by3c (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t carry)
  1175. {
  1176.   mp_ptr     spcopy;
  1177.   mp_limb_t  c, cs;
  1178.   ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
  1179.   ASSERT (size >= 1);
  1180.   ASSERT (carry <= 2);
  1181.   ASSERT_MPN (sp, size);
  1182.   spcopy = refmpn_malloc_limbs (size);
  1183.   cs = refmpn_sub_1 (spcopy, sp, size, carry);
  1184.   for (c = 0; c <= 2; c++)
  1185.     if (refmpn_divmod_1c (rp, spcopy, size, CNST_LIMB(3), c) == 0)
  1186.       goto done;
  1187.   ASSERT_FAIL (no value of c satisfies);
  1188.  done:
  1189.   c += cs;
  1190.   ASSERT (c <= 2);
  1191.   free (spcopy);
  1192.   return c;
  1193. }
  1194. mp_limb_t
  1195. refmpn_divexact_by3 (mp_ptr rp, mp_srcptr sp, mp_size_t size)
  1196. {
  1197.   return refmpn_divexact_by3c (rp, sp, size, CNST_LIMB(0));
  1198. }
  1199. /* The same as mpn/generic/mul_basecase.c, but using refmpn functions. */
  1200. void
  1201. refmpn_mul_basecase (mp_ptr prodp,
  1202.      mp_srcptr up, mp_size_t usize,
  1203.      mp_srcptr vp, mp_size_t vsize)
  1204. {
  1205.   mp_size_t i;
  1206.   ASSERT (! refmpn_overlap_p (prodp, usize+vsize, up, usize));
  1207.   ASSERT (! refmpn_overlap_p (prodp, usize+vsize, vp, vsize));
  1208.   ASSERT (usize >= vsize);
  1209.   ASSERT (vsize >= 1);
  1210.   ASSERT_MPN (up, usize);
  1211.   ASSERT_MPN (vp, vsize);
  1212.   prodp[usize] = refmpn_mul_1 (prodp, up, usize, vp[0]);
  1213.   for (i = 1; i < vsize; i++)
  1214.     prodp[usize+i] = refmpn_addmul_1 (prodp+i, up, usize, vp[i]);
  1215. }
  1216. #define TOOM3_THRESHOLD (MAX (MUL_TOOM33_THRESHOLD, SQR_TOOM3_THRESHOLD))
  1217. #define TOOM4_THRESHOLD (MAX (MUL_TOOM44_THRESHOLD, SQR_TOOM4_THRESHOLD))
  1218. #if WANT_FFT
  1219. #define FFT_THRESHOLD (MAX (MUL_FFT_THRESHOLD, SQR_FFT_THRESHOLD))
  1220. #else
  1221. #define FFT_THRESHOLD MP_SIZE_T_MAX /* don't use toom44 here */
  1222. #endif
  1223. void
  1224. refmpn_mul (mp_ptr wp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
  1225. {
  1226.   mp_ptr tp;
  1227.   mp_size_t tn;
  1228.   mp_limb_t cy;
  1229.   if (vn < TOOM3_THRESHOLD)
  1230.     {
  1231.       /* In the mpn_mul_basecase and mpn_kara_mul_n range, use our own
  1232.  mul_basecase.  */
  1233.       if (vn != 0)
  1234. refmpn_mul_basecase (wp, up, un, vp, vn);
  1235.       else
  1236. MPN_ZERO (wp, un);
  1237.       return;
  1238.     }
  1239.   if (vn < TOOM4_THRESHOLD)
  1240.     {
  1241.       /* In the mpn_toom33_mul range, use mpn_toom22_mul.  */
  1242.       tn = 2 * vn + mpn_toom22_mul_itch (vn, vn);
  1243.       tp = refmpn_malloc_limbs (tn);
  1244.       mpn_toom22_mul (tp, up, vn, vp, vn, tp + 2 * vn);
  1245.     }
  1246.   else if (vn < FFT_THRESHOLD)
  1247.     {
  1248.       /* In the mpn_toom44_mul range, use mpn_toom33_mul.  */
  1249.       tn = 2 * vn + mpn_toom33_mul_itch (vn, vn);
  1250.       tp = refmpn_malloc_limbs (tn);
  1251.       mpn_toom33_mul (tp, up, vn, vp, vn, tp + 2 * vn);
  1252.     }
  1253.   else
  1254.     {
  1255.       /* Finally, for the largest operands, use mpn_toom44_mul.  */
  1256.       tn = 2 * vn + mpn_toom44_mul_itch (vn, vn);
  1257.       tp = refmpn_malloc_limbs (tn);
  1258.       mpn_toom44_mul (tp, up, vn, vp, vn, tp + 2 * vn);
  1259.     }
  1260.   if (un != vn)
  1261.     {
  1262.       if (un - vn < vn)
  1263. refmpn_mul (wp + vn, vp, vn, up + vn, un - vn);
  1264.       else
  1265. refmpn_mul (wp + vn, up + vn, un - vn, vp, vn);
  1266.       MPN_COPY (wp, tp, vn);
  1267.       cy = refmpn_add (wp + vn, wp + vn, un, tp + vn, vn);
  1268.     }
  1269.   else
  1270.     {
  1271.       MPN_COPY (wp, tp, 2 * vn);
  1272.     }
  1273.   free (tp);
  1274. }
  1275. void
  1276. refmpn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
  1277. {
  1278.   refmpn_mul (prodp, up, size, vp, size);
  1279. }
  1280. void
  1281. refmpn_mullo_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
  1282. {
  1283.   mp_ptr tp = refmpn_malloc_limbs (2*size);
  1284.   refmpn_mul (tp, up, size, vp, size);
  1285.   refmpn_copyi (prodp, tp, size);
  1286.   free (tp);
  1287. }
  1288. void
  1289. refmpn_sqr (mp_ptr dst, mp_srcptr src, mp_size_t size)
  1290. {
  1291.   refmpn_mul (dst, src, size, src, size);
  1292. }
  1293. /* Allowing usize<vsize, usize==0 or vsize==0. */
  1294. void
  1295. refmpn_mul_any (mp_ptr prodp,
  1296.      mp_srcptr up, mp_size_t usize,
  1297.      mp_srcptr vp, mp_size_t vsize)
  1298. {
  1299.   ASSERT (! refmpn_overlap_p (prodp, usize+vsize, up, usize));
  1300.   ASSERT (! refmpn_overlap_p (prodp, usize+vsize, vp, vsize));
  1301.   ASSERT (usize >= 0);
  1302.   ASSERT (vsize >= 0);
  1303.   ASSERT_MPN (up, usize);
  1304.   ASSERT_MPN (vp, vsize);
  1305.   if (usize == 0)
  1306.     {
  1307.       refmpn_fill (prodp, vsize, CNST_LIMB(0));
  1308.       return;
  1309.     }
  1310.   if (vsize == 0)
  1311.     {
  1312.       refmpn_fill (prodp, usize, CNST_LIMB(0));
  1313.       return;
  1314.     }
  1315.   if (usize >= vsize)
  1316.     refmpn_mul (prodp, up, usize, vp, vsize);
  1317.   else
  1318.     refmpn_mul (prodp, vp, vsize, up, usize);
  1319. }
  1320. mp_limb_t
  1321. refmpn_gcd_1 (mp_srcptr xp, mp_size_t xsize, mp_limb_t y)
  1322. {
  1323.   mp_limb_t  x;
  1324.   int  twos;
  1325.   ASSERT (y != 0);
  1326.   ASSERT (! refmpn_zero_p (xp, xsize));
  1327.   ASSERT_MPN (xp, xsize);
  1328.   ASSERT_LIMB (y);
  1329.   x = refmpn_mod_1 (xp, xsize, y);
  1330.   if (x == 0)
  1331.     return y;
  1332.   twos = 0;
  1333.   while ((x & 1) == 0 && (y & 1) == 0)
  1334.     {
  1335.       x >>= 1;
  1336.       y >>= 1;
  1337.       twos++;
  1338.     }
  1339.   for (;;)
  1340.     {
  1341.       while ((x & 1) == 0)  x >>= 1;
  1342.       while ((y & 1) == 0)  y >>= 1;
  1343.       if (x < y)
  1344. MP_LIMB_T_SWAP (x, y);
  1345.       x -= y;
  1346.       if (x == 0)
  1347. break;
  1348.     }
  1349.   return y << twos;
  1350. }
  1351. /* Based on the full limb x, not nails. */
  1352. unsigned
  1353. refmpn_count_leading_zeros (mp_limb_t x)
  1354. {
  1355.   unsigned  n = 0;
  1356.   ASSERT (x != 0);
  1357.   while ((x & GMP_LIMB_HIGHBIT) == 0)
  1358.     {
  1359.       x <<= 1;
  1360.       n++;
  1361.     }
  1362.   return n;
  1363. }
  1364. /* Full limbs allowed, not limited to nails. */
  1365. unsigned
  1366. refmpn_count_trailing_zeros (mp_limb_t x)
  1367. {
  1368.   unsigned  n = 0;
  1369.   ASSERT (x != 0);
  1370.   ASSERT_LIMB (x);
  1371.   while ((x & 1) == 0)
  1372.     {
  1373.       x >>= 1;
  1374.       n++;
  1375.     }
  1376.   return n;
  1377. }
  1378. /* Strip factors of two (low zero bits) from {p,size} by right shifting.
  1379.    The return value is the number of twos stripped.  */
  1380. mp_size_t
  1381. refmpn_strip_twos (mp_ptr p, mp_size_t size)
  1382. {
  1383.   mp_size_t  limbs;
  1384.   unsigned   shift;
  1385.   ASSERT (size >= 1);
  1386.   ASSERT (! refmpn_zero_p (p, size));
  1387.   ASSERT_MPN (p, size);
  1388.   for (limbs = 0; p[0] == 0; limbs++)
  1389.     {
  1390.       refmpn_copyi (p, p+1, size-1);
  1391.       p[size-1] = 0;
  1392.     }
  1393.   shift = refmpn_count_trailing_zeros (p[0]);
  1394.   if (shift)
  1395.     refmpn_rshift (p, p, size, shift);
  1396.   return limbs*GMP_NUMB_BITS + shift;
  1397. }
  1398. mp_limb_t
  1399. refmpn_gcd (mp_ptr gp, mp_ptr xp, mp_size_t xsize, mp_ptr yp, mp_size_t ysize)
  1400. {
  1401.   int       cmp;
  1402.   ASSERT (ysize >= 1);
  1403.   ASSERT (xsize >= ysize);
  1404.   ASSERT ((xp[0] & 1) != 0);
  1405.   ASSERT ((yp[0] & 1) != 0);
  1406.   /* ASSERT (xp[xsize-1] != 0); */  /* don't think x needs to be odd */
  1407.   ASSERT (yp[ysize-1] != 0);
  1408.   ASSERT (refmpn_overlap_fullonly_p (gp, xp, xsize));
  1409.   ASSERT (refmpn_overlap_fullonly_p (gp, yp, ysize));
  1410.   ASSERT (! refmpn_overlap_p (xp, xsize, yp, ysize));
  1411.   if (xsize == ysize)
  1412.     ASSERT (refmpn_msbone (xp[xsize-1]) >= refmpn_msbone (yp[ysize-1]));
  1413.   ASSERT_MPN (xp, xsize);
  1414.   ASSERT_MPN (yp, ysize);
  1415.   refmpn_strip_twos (xp, xsize);
  1416.   MPN_NORMALIZE (xp, xsize);
  1417.   MPN_NORMALIZE (yp, ysize);
  1418.   for (;;)
  1419.     {
  1420.       cmp = refmpn_cmp_twosizes (xp, xsize, yp, ysize);
  1421.       if (cmp == 0)
  1422. break;
  1423.       if (cmp < 0)
  1424. MPN_PTR_SWAP (xp,xsize, yp,ysize);
  1425.       ASSERT_NOCARRY (refmpn_sub (xp, xp, xsize, yp, ysize));
  1426.       refmpn_strip_twos (xp, xsize);
  1427.       MPN_NORMALIZE (xp, xsize);
  1428.     }
  1429.   refmpn_copyi (gp, xp, xsize);
  1430.   return xsize;
  1431. }
  1432. unsigned long
  1433. ref_popc_limb (mp_limb_t src)
  1434. {
  1435.   unsigned long  count;
  1436.   int  i;
  1437.   count = 0;
  1438.   for (i = 0; i < GMP_LIMB_BITS; i++)
  1439.     {
  1440.       count += (src & 1);
  1441.       src >>= 1;
  1442.     }
  1443.   return count;
  1444. }
  1445. unsigned long
  1446. refmpn_popcount (mp_srcptr sp, mp_size_t size)
  1447. {
  1448.   unsigned long  count = 0;
  1449.   mp_size_t  i;
  1450.   ASSERT (size >= 0);
  1451.   ASSERT_MPN (sp, size);
  1452.   for (i = 0; i < size; i++)
  1453.     count += ref_popc_limb (sp[i]);
  1454.   return count;
  1455. }
  1456. unsigned long
  1457. refmpn_hamdist (mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
  1458. {
  1459.   mp_ptr  d;
  1460.   unsigned long  count;
  1461.   ASSERT (size >= 0);
  1462.   ASSERT_MPN (s1p, size);
  1463.   ASSERT_MPN (s2p, size);
  1464.   if (size == 0)
  1465.     return 0;
  1466.   d = refmpn_malloc_limbs (size);
  1467.   refmpn_xor_n (d, s1p, s2p, size);
  1468.   count = refmpn_popcount (d, size);
  1469.   free (d);
  1470.   return count;
  1471. }
  1472. /* set r to a%d */
  1473. void
  1474. refmpn_mod2 (mp_limb_t r[2], const mp_limb_t a[2], const mp_limb_t d[2])
  1475. {
  1476.   mp_limb_t  D[2];
  1477.   int        n;
  1478.   ASSERT (! refmpn_overlap_p (r, (mp_size_t) 2, d, (mp_size_t) 2));
  1479.   ASSERT_MPN (a, 2);
  1480.   ASSERT_MPN (d, 2);
  1481.   D[1] = d[1], D[0] = d[0];
  1482.   r[1] = a[1], r[0] = a[0];
  1483.   n = 0;
  1484.   for (;;)
  1485.     {
  1486.       if (D[1] & GMP_NUMB_HIGHBIT)
  1487. break;
  1488.       if (refmpn_cmp (r, D, (mp_size_t) 2) <= 0)
  1489. break;
  1490.       refmpn_lshift (D, D, (mp_size_t) 2, 1);
  1491.       n++;
  1492.       ASSERT (n <= GMP_NUMB_BITS);
  1493.     }
  1494.   while (n >= 0)
  1495.     {
  1496.       if (refmpn_cmp (r, D, (mp_size_t) 2) >= 0)
  1497. ASSERT_NOCARRY (refmpn_sub_n (r, r, D, (mp_size_t) 2));
  1498.       refmpn_rshift (D, D, (mp_size_t) 2, 1);
  1499.       n--;
  1500.     }
  1501.   ASSERT (refmpn_cmp (r, d, (mp_size_t) 2) < 0);
  1502. }
  1503. /* Similar to the old mpn/generic/sb_divrem_mn.c, but somewhat simplified, in
  1504.    particular the trial quotient is allowed to be 2 too big. */
  1505. mp_limb_t
  1506. refmpn_sb_div_qr (mp_ptr qp,
  1507.   mp_ptr np, mp_size_t nsize,
  1508.   mp_srcptr dp, mp_size_t dsize)
  1509. {
  1510.   mp_limb_t  retval = 0;
  1511.   mp_size_t  i;
  1512.   mp_limb_t  d1 = dp[dsize-1];
  1513.   mp_ptr     np_orig = refmpn_memdup_limbs (np, nsize);
  1514.   ASSERT (nsize >= dsize);
  1515.   /* ASSERT (dsize > 2); */
  1516.   ASSERT (dsize >= 2);
  1517.   ASSERT (dp[dsize-1] & GMP_NUMB_HIGHBIT);
  1518.   ASSERT (! refmpn_overlap_p (qp, nsize-dsize, np, nsize) || qp+dsize >= np);
  1519.   ASSERT_MPN (np, nsize);
  1520.   ASSERT_MPN (dp, dsize);
  1521.   i = nsize-dsize;
  1522.   if (refmpn_cmp (np+i, dp, dsize) >= 0)
  1523.     {
  1524.       ASSERT_NOCARRY (refmpn_sub_n (np+i, np+i, dp, dsize));
  1525.       retval = 1;
  1526.     }
  1527.   for (i--; i >= 0; i--)
  1528.     {
  1529.       mp_limb_t  n0 = np[i+dsize];
  1530.       mp_limb_t  n1 = np[i+dsize-1];
  1531.       mp_limb_t  q, dummy_r;
  1532.       ASSERT (n0 <= d1);
  1533.       if (n0 == d1)
  1534. q = GMP_NUMB_MAX;
  1535.       else
  1536. q = refmpn_udiv_qrnnd (&dummy_r, n0, n1 << GMP_NAIL_BITS,
  1537.        d1 << GMP_NAIL_BITS);
  1538.       n0 -= refmpn_submul_1 (np+i, dp, dsize, q);
  1539.       ASSERT (n0 == 0 || n0 == MP_LIMB_T_MAX);
  1540.       if (n0)
  1541. {
  1542.   q--;
  1543.   if (! refmpn_add_n (np+i, np+i, dp, dsize))
  1544.     {
  1545.       q--;
  1546.       ASSERT_CARRY (refmpn_add_n (np+i, np+i, dp, dsize));
  1547.     }
  1548. }
  1549.       np[i+dsize] = 0;
  1550.       qp[i] = q;
  1551.     }
  1552.   /* remainder < divisor */
  1553. #if 0 /* ASSERT triggers gcc 4.2.1 bug */
  1554.   ASSERT (refmpn_cmp (np, dp, dsize) < 0);
  1555. #endif
  1556.   /* multiply back to original */
  1557.   {
  1558.     mp_ptr  mp = refmpn_malloc_limbs (nsize);
  1559.     refmpn_mul_any (mp, qp, nsize-dsize, dp, dsize);
  1560.     if (retval)
  1561.       ASSERT_NOCARRY (refmpn_add_n (mp+nsize-dsize,mp+nsize-dsize, dp, dsize));
  1562.     ASSERT_NOCARRY (refmpn_add (mp, mp, nsize, np, dsize));
  1563.     ASSERT (refmpn_cmp (mp, np_orig, nsize) == 0);
  1564.     free (mp);
  1565.   }
  1566.   free (np_orig);
  1567.   return retval;
  1568. }
  1569. /* Similar to the old mpn/generic/sb_divrem_mn.c, but somewhat simplified, in
  1570.    particular the trial quotient is allowed to be 2 too big. */
  1571. void
  1572. refmpn_tdiv_qr (mp_ptr qp, mp_ptr rp, mp_size_t qxn,
  1573. mp_ptr np, mp_size_t nsize,
  1574. mp_srcptr dp, mp_size_t dsize)
  1575. {
  1576.   ASSERT (qxn == 0);
  1577.   ASSERT_MPN (np, nsize);
  1578.   ASSERT_MPN (dp, dsize);
  1579.   ASSERT (dsize > 0);
  1580.   ASSERT (dp[dsize-1] != 0);
  1581.   if (dsize == 1)
  1582.     {
  1583.       rp[0] = refmpn_divmod_1 (qp, np, nsize, dp[0]);
  1584.       return;
  1585.     }
  1586.   else
  1587.     {
  1588.       mp_ptr  n2p = refmpn_malloc_limbs (nsize+1);
  1589.       mp_ptr  d2p = refmpn_malloc_limbs (dsize);
  1590.       int     norm = refmpn_count_leading_zeros (dp[dsize-1]) - GMP_NAIL_BITS;
  1591.       n2p[nsize] = refmpn_lshift_or_copy (n2p, np, nsize, norm);
  1592.       ASSERT_NOCARRY (refmpn_lshift_or_copy (d2p, dp, dsize, norm));
  1593.       refmpn_sb_div_qr (qp, n2p, nsize+1, d2p, dsize);
  1594.       refmpn_rshift_or_copy (rp, n2p, dsize, norm);
  1595.       /* ASSERT (refmpn_zero_p (tp+dsize, nsize-dsize)); */
  1596.       free (n2p);
  1597.       free (d2p);
  1598.     }
  1599. }
  1600. void
  1601. refmpn_redc_1 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_limb_t invm)
  1602. {
  1603.   mp_size_t j;
  1604.   mp_limb_t cy;
  1605.   ASSERT_MPN (up, 2*n);
  1606.   /* ASSERT about directed overlap rp, up */
  1607.   /* ASSERT about overlap rp, mp */
  1608.   /* ASSERT about overlap up, mp */
  1609.   for (j = n - 1; j >= 0; j--)
  1610.     {
  1611.       up[0] = mpn_addmul_1 (up, mp, n, (up[0] * invm) & GMP_NUMB_MASK);
  1612.       up++;
  1613.     }
  1614.   cy = mpn_add_n (rp, up, up - n, n);
  1615.   if (cy != 0)
  1616.     mpn_sub_n (rp, rp, mp, n);
  1617. }
  1618. size_t
  1619. refmpn_get_str (unsigned char *dst, int base, mp_ptr src, mp_size_t size)
  1620. {
  1621.   unsigned char  *d;
  1622.   size_t  dsize;
  1623.   ASSERT (size >= 0);
  1624.   ASSERT (base >= 2);
  1625.   ASSERT (base < numberof (mp_bases));
  1626.   ASSERT (size == 0 || src[size-1] != 0);
  1627.   ASSERT_MPN (src, size);
  1628.   MPN_SIZEINBASE (dsize, src, size, base);
  1629.   ASSERT (dsize >= 1);
  1630.   ASSERT (! byte_overlap_p (dst, (mp_size_t) dsize, src, size * BYTES_PER_MP_LIMB));
  1631.   if (size == 0)
  1632.     {
  1633.       dst[0] = 0;
  1634.       return 1;
  1635.     }
  1636.   /* don't clobber input for power of 2 bases */
  1637.   if (POW2_P (base))
  1638.     src = refmpn_memdup_limbs (src, size);
  1639.   d = dst + dsize;
  1640.   do
  1641.     {
  1642.       d--;
  1643.       ASSERT (d >= dst);
  1644.       *d = refmpn_divrem_1 (src, (mp_size_t) 0, src, size, (mp_limb_t) base);
  1645.       size -= (src[size-1] == 0);
  1646.     }
  1647.   while (size != 0);
  1648.   /* Move result back and decrement dsize if we didn't generate
  1649.      the maximum possible digits.  */
  1650.   if (d != dst)
  1651.     {
  1652.       size_t i;
  1653.       dsize -= d - dst;
  1654.       for (i = 0; i < dsize; i++)
  1655. dst[i] = d[i];
  1656.     }
  1657.   if (POW2_P (base))
  1658.     free (src);
  1659.   return dsize;
  1660. }
  1661. mp_limb_t
  1662. ref_bswap_limb (mp_limb_t src)
  1663. {
  1664.   mp_limb_t  dst;
  1665.   int        i;
  1666.   dst = 0;
  1667.   for (i = 0; i < BYTES_PER_MP_LIMB; i++)
  1668.     {
  1669.       dst = (dst << 8) + (src & 0xFF);
  1670.       src >>= 8;
  1671.     }
  1672.   return dst;
  1673. }
  1674. /* These random functions are mostly for transitional purposes while adding
  1675.    nail support, since they're independent of the normal mpn routines.  They
  1676.    can probably be removed when those normal routines are reliable, though
  1677.    perhaps something independent would still be useful at times.  */
  1678. #if GMP_LIMB_BITS == 32
  1679. #define RAND_A  CNST_LIMB(0x29CF535)
  1680. #endif
  1681. #if GMP_LIMB_BITS == 64
  1682. #define RAND_A  CNST_LIMB(0xBAECD515DAF0B49D)
  1683. #endif
  1684. mp_limb_t  refmpn_random_seed;
  1685. mp_limb_t
  1686. refmpn_random_half (void)
  1687. {
  1688.   refmpn_random_seed = refmpn_random_seed * RAND_A + 1;
  1689.   return (refmpn_random_seed >> GMP_LIMB_BITS/2);
  1690. }
  1691. mp_limb_t
  1692. refmpn_random_limb (void)
  1693. {
  1694.   return ((refmpn_random_half () << (GMP_LIMB_BITS/2))
  1695.    | refmpn_random_half ()) & GMP_NUMB_MASK;
  1696. }
  1697. void
  1698. refmpn_random (mp_ptr ptr, mp_size_t size)
  1699. {
  1700.   mp_size_t  i;
  1701.   if (GMP_NAIL_BITS == 0)
  1702.     {
  1703.       mpn_random (ptr, size);
  1704.       return;
  1705.     }
  1706.   for (i = 0; i < size; i++)
  1707.     ptr[i] = refmpn_random_limb ();
  1708. }
  1709. void
  1710. refmpn_random2 (mp_ptr ptr, mp_size_t size)
  1711. {
  1712.   mp_size_t  i;
  1713.   mp_limb_t  bit, mask, limb;
  1714.   int        run;
  1715.   if (GMP_NAIL_BITS == 0)
  1716.     {
  1717.       mpn_random2 (ptr, size);
  1718.       return;
  1719.     }
  1720. #define RUN_MODULUS  32
  1721.   /* start with ones at a random pos in the high limb */
  1722.   bit = CNST_LIMB(1) << (refmpn_random_half () % GMP_NUMB_BITS);
  1723.   mask = 0;
  1724.   run = 0;
  1725.   for (i = size-1; i >= 0; i--)
  1726.     {
  1727.       limb = 0;
  1728.       do
  1729. {
  1730.   if (run == 0)
  1731.     {
  1732.       run = (refmpn_random_half () % RUN_MODULUS) + 1;
  1733.       mask = ~mask;
  1734.     }
  1735.   limb |= (bit & mask);
  1736.   bit >>= 1;
  1737.   run--;
  1738. }
  1739.       while (bit != 0);
  1740.       ptr[i] = limb;
  1741.       bit = GMP_NUMB_HIGHBIT;
  1742.     }
  1743. }
  1744. /* This is a simple bitwise algorithm working high to low across "s" and
  1745.    testing each time whether setting the bit would make s^2 exceed n.  */
  1746. mp_size_t
  1747. refmpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr np, mp_size_t nsize)
  1748. {
  1749.   mp_ptr     tp, dp;
  1750.   mp_size_t  ssize, talloc, tsize, dsize, ret, ilimbs;
  1751.   unsigned   ibit;
  1752.   long       i;
  1753.   mp_limb_t  c;
  1754.   ASSERT (nsize >= 0);
  1755.   /* If n==0, then s=0 and r=0.  */
  1756.   if (nsize == 0)
  1757.     return 0;
  1758.   ASSERT (np[nsize - 1] != 0);
  1759.   ASSERT (rp == NULL || MPN_SAME_OR_SEPARATE_P (np, rp, nsize));
  1760.   ASSERT (rp == NULL || ! MPN_OVERLAP_P (sp, (nsize + 1) / 2, rp, nsize));
  1761.   ASSERT (! MPN_OVERLAP_P (sp, (nsize + 1) / 2, np, nsize));
  1762.   /* root */
  1763.   ssize = (nsize+1)/2;
  1764.   refmpn_zero (sp, ssize);
  1765.   /* the remainder so far */
  1766.   dp = refmpn_memdup_limbs (np, nsize);
  1767.   dsize = nsize;
  1768.   /* temporary */
  1769.   talloc = 2*ssize + 1;
  1770.   tp = refmpn_malloc_limbs (talloc);
  1771.   for (i = GMP_NUMB_BITS * ssize - 1; i >= 0; i--)
  1772.     {
  1773.       /* t = 2*s*2^i + 2^(2*i), being the amount s^2 will increase by if 2^i
  1774.  is added to it */
  1775.       ilimbs = (i+1) / GMP_NUMB_BITS;
  1776.       ibit = (i+1) % GMP_NUMB_BITS;
  1777.       refmpn_zero (tp, ilimbs);
  1778.       c = refmpn_lshift_or_copy (tp+ilimbs, sp, ssize, ibit);
  1779.       tsize = ilimbs + ssize;
  1780.       tp[tsize] = c;
  1781.       tsize += (c != 0);
  1782.       ilimbs = (2*i) / GMP_NUMB_BITS;
  1783.       ibit = (2*i) % GMP_NUMB_BITS;
  1784.       if (ilimbs + 1 > tsize)
  1785. {
  1786.   refmpn_zero_extend (tp, tsize, ilimbs + 1);
  1787.   tsize = ilimbs + 1;
  1788. }
  1789.       c = refmpn_add_1 (tp+ilimbs, tp+ilimbs, tsize-ilimbs,
  1790. CNST_LIMB(1) << ibit);
  1791.       ASSERT (tsize < talloc);
  1792.       tp[tsize] = c;
  1793.       tsize += (c != 0);
  1794.       if (refmpn_cmp_twosizes (dp, dsize, tp, tsize) >= 0)
  1795. {
  1796.   /* set this bit in s and subtract from the remainder */
  1797.   refmpn_setbit (sp, i);
  1798.   ASSERT_NOCARRY (refmpn_sub_n (dp, dp, tp, dsize));
  1799.   dsize = refmpn_normalize (dp, dsize);
  1800. }
  1801.     }
  1802.   if (rp == NULL)
  1803.     {
  1804.       ret = ! refmpn_zero_p (dp, dsize);
  1805.     }
  1806.   else
  1807.     {
  1808.       ASSERT (dsize == 0 || dp[dsize-1] != 0);
  1809.       refmpn_copy (rp, dp, dsize);
  1810.       ret = dsize;
  1811.     }
  1812.   free (dp);
  1813.   free (tp);
  1814.   return ret;
  1815. }