Home | History | Annotate | Line # | Download | only in generic
      1      1.1  mrg /* jacobi_2.c
      2      1.1  mrg 
      3      1.1  mrg    THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES.  IT IS ONLY
      4      1.1  mrg    SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES.  IN FACT, IT IS ALMOST
      5      1.1  mrg    GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
      6      1.1  mrg 
      7  1.1.1.2  mrg Copyright 1996, 1998, 2000-2004, 2008, 2010 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  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  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.1.2  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 #include "gmp-impl.h"
     36      1.1  mrg #include "longlong.h"
     37      1.1  mrg 
     38      1.1  mrg #ifndef JACOBI_2_METHOD
     39      1.1  mrg #define JACOBI_2_METHOD 2
     40      1.1  mrg #endif
     41      1.1  mrg 
     42      1.1  mrg /* Computes (a / b) where b is odd, and a and b are otherwise arbitrary
     43      1.1  mrg    two-limb numbers. */
     44      1.1  mrg #if JACOBI_2_METHOD == 1
     45      1.1  mrg int
     46      1.1  mrg mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit)
     47      1.1  mrg {
     48      1.1  mrg   mp_limb_t ah, al, bh, bl;
     49      1.1  mrg   int c;
     50      1.1  mrg 
     51      1.1  mrg   al = ap[0];
     52      1.1  mrg   ah = ap[1];
     53      1.1  mrg   bl = bp[0];
     54      1.1  mrg   bh = bp[1];
     55      1.1  mrg 
     56      1.1  mrg   ASSERT (bl & 1);
     57      1.1  mrg 
     58      1.1  mrg   bl = ((bh << (GMP_NUMB_BITS - 1)) & GMP_NUMB_MASK) | (bl >> 1);
     59      1.1  mrg   bh >>= 1;
     60      1.1  mrg 
     61      1.1  mrg   if ( (bh | bl) == 0)
     62      1.1  mrg     return 1 - 2*(bit & 1);
     63      1.1  mrg 
     64      1.1  mrg   if ( (ah | al) == 0)
     65      1.1  mrg     return 0;
     66      1.1  mrg 
     67      1.1  mrg   if (al == 0)
     68      1.1  mrg     {
     69      1.1  mrg       al = ah;
     70      1.1  mrg       ah = 0;
     71      1.1  mrg       bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1));
     72      1.1  mrg     }
     73      1.1  mrg   count_trailing_zeros (c, al);
     74      1.1  mrg   bit ^= c & (bl ^ (bl >> 1));
     75      1.1  mrg 
     76      1.1  mrg   c++;
     77      1.1  mrg   if (UNLIKELY (c == GMP_NUMB_BITS))
     78      1.1  mrg     {
     79      1.1  mrg       al = ah;
     80      1.1  mrg       ah = 0;
     81      1.1  mrg     }
     82      1.1  mrg   else
     83      1.1  mrg     {
     84      1.1  mrg       al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
     85      1.1  mrg       ah >>= c;
     86      1.1  mrg     }
     87      1.1  mrg   while ( (ah | bh) > 0)
     88      1.1  mrg     {
     89      1.1  mrg       mp_limb_t th, tl;
     90      1.1  mrg       mp_limb_t bgta;
     91      1.1  mrg 
     92      1.1  mrg       sub_ddmmss (th, tl, ah, al, bh, bl);
     93      1.1  mrg       if ( (tl | th) == 0)
     94      1.1  mrg 	return 0;
     95      1.1  mrg 
     96      1.1  mrg       bgta = LIMB_HIGHBIT_TO_MASK (th);
     97      1.1  mrg 
     98      1.1  mrg       /* If b > a, invoke reciprocity */
     99      1.1  mrg       bit ^= (bgta & al & bl);
    100      1.1  mrg 
    101      1.1  mrg       /* b <-- min (a, b) */
    102      1.1  mrg       add_ssaaaa (bh, bl, bh, bl, th & bgta, tl & bgta);
    103      1.1  mrg 
    104      1.1  mrg       if ( (bh | bl) == 0)
    105      1.1  mrg 	return 1 - 2*(bit & 1);
    106      1.1  mrg 
    107      1.1  mrg       /* a <-- |a - b| */
    108      1.1  mrg       al = (bgta ^ tl) - bgta;
    109      1.1  mrg       ah = (bgta ^ th);
    110      1.1  mrg 
    111      1.1  mrg       if (UNLIKELY (al == 0))
    112      1.1  mrg 	{
    113      1.1  mrg 	  /* If b > a, al == 0 implies that we have a carry to
    114      1.1  mrg 	     propagate. */
    115      1.1  mrg 	  al = ah - bgta;
    116      1.1  mrg 	  ah = 0;
    117      1.1  mrg 	  bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1));
    118      1.1  mrg 	}
    119      1.1  mrg       count_trailing_zeros (c, al);
    120      1.1  mrg       c++;
    121      1.1  mrg       bit ^= c & (bl ^ (bl >> 1));
    122      1.1  mrg 
    123      1.1  mrg       if (UNLIKELY (c == GMP_NUMB_BITS))
    124      1.1  mrg 	{
    125      1.1  mrg 	  al = ah;
    126      1.1  mrg 	  ah = 0;
    127      1.1  mrg 	}
    128      1.1  mrg       else
    129      1.1  mrg 	{
    130      1.1  mrg 	  al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
    131      1.1  mrg 	  ah >>= c;
    132      1.1  mrg 	}
    133      1.1  mrg     }
    134      1.1  mrg 
    135      1.1  mrg   ASSERT (bl > 0);
    136      1.1  mrg 
    137      1.1  mrg   while ( (al | bl) & GMP_LIMB_HIGHBIT)
    138      1.1  mrg     {
    139      1.1  mrg       /* Need an extra comparison to get the mask. */
    140      1.1  mrg       mp_limb_t t = al - bl;
    141      1.1  mrg       mp_limb_t bgta = - (bl > al);
    142      1.1  mrg 
    143      1.1  mrg       if (t == 0)
    144      1.1  mrg 	return 0;
    145      1.1  mrg 
    146      1.1  mrg       /* If b > a, invoke reciprocity */
    147      1.1  mrg       bit ^= (bgta & al & bl);
    148      1.1  mrg 
    149      1.1  mrg       /* b <-- min (a, b) */
    150      1.1  mrg       bl += (bgta & t);
    151      1.1  mrg 
    152      1.1  mrg       /* a <-- |a - b| */
    153      1.1  mrg       al = (t ^ bgta) - bgta;
    154      1.1  mrg 
    155      1.1  mrg       /* Number of trailing zeros is the same no matter if we look at
    156      1.1  mrg        * t or a, but using t gives more parallelism. */
    157      1.1  mrg       count_trailing_zeros (c, t);
    158      1.1  mrg       c ++;
    159      1.1  mrg       /* (2/b) = -1 if b = 3 or 5 mod 8 */
    160      1.1  mrg       bit ^= c & (bl ^ (bl >> 1));
    161      1.1  mrg 
    162      1.1  mrg       if (UNLIKELY (c == GMP_NUMB_BITS))
    163      1.1  mrg 	return 1 - 2*(bit & 1);
    164      1.1  mrg 
    165      1.1  mrg       al >>= c;
    166      1.1  mrg     }
    167      1.1  mrg 
    168      1.1  mrg   /* Here we have a little impedance mismatch. Better to inline it? */
    169      1.1  mrg   return mpn_jacobi_base (2*al+1, 2*bl+1, bit << 1);
    170      1.1  mrg }
    171      1.1  mrg #elif JACOBI_2_METHOD == 2
    172      1.1  mrg int
    173      1.1  mrg mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit)
    174      1.1  mrg {
    175      1.1  mrg   mp_limb_t ah, al, bh, bl;
    176      1.1  mrg   int c;
    177      1.1  mrg 
    178      1.1  mrg   al = ap[0];
    179      1.1  mrg   ah = ap[1];
    180      1.1  mrg   bl = bp[0];
    181      1.1  mrg   bh = bp[1];
    182      1.1  mrg 
    183      1.1  mrg   ASSERT (bl & 1);
    184      1.1  mrg 
    185      1.1  mrg   /* Use bit 1. */
    186      1.1  mrg   bit <<= 1;
    187      1.1  mrg 
    188      1.1  mrg   if (bh == 0 && bl == 1)
    189      1.1  mrg     /* (a|1) = 1 */
    190      1.1  mrg     return 1 - (bit & 2);
    191      1.1  mrg 
    192      1.1  mrg   if (al == 0)
    193      1.1  mrg     {
    194      1.1  mrg       if (ah == 0)
    195      1.1  mrg 	/* (0|b) = 0, b > 1 */
    196      1.1  mrg 	return 0;
    197      1.1  mrg 
    198      1.1  mrg       count_trailing_zeros (c, ah);
    199      1.1  mrg       bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
    200      1.1  mrg 
    201      1.1  mrg       al = bl;
    202      1.1  mrg       bl = ah >> c;
    203      1.1  mrg 
    204      1.1  mrg       if (bl == 1)
    205      1.1  mrg 	/* (1|b) = 1 */
    206      1.1  mrg 	return 1 - (bit & 2);
    207      1.1  mrg 
    208      1.1  mrg       ah = bh;
    209      1.1  mrg 
    210      1.1  mrg       bit ^= al & bl;
    211      1.1  mrg 
    212      1.1  mrg       goto b_reduced;
    213      1.1  mrg     }
    214      1.1  mrg   if ( (al & 1) == 0)
    215      1.1  mrg     {
    216      1.1  mrg       count_trailing_zeros (c, al);
    217      1.1  mrg 
    218      1.1  mrg       al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
    219      1.1  mrg       ah >>= c;
    220      1.1  mrg       bit ^= (c << 1) & (bl ^ (bl >> 1));
    221      1.1  mrg     }
    222      1.1  mrg   if (ah == 0)
    223      1.1  mrg     {
    224      1.1  mrg       if (bh > 0)
    225      1.1  mrg 	{
    226      1.1  mrg 	  bit ^= al & bl;
    227      1.1  mrg 	  MP_LIMB_T_SWAP (al, bl);
    228      1.1  mrg 	  ah = bh;
    229      1.1  mrg 	  goto b_reduced;
    230      1.1  mrg 	}
    231      1.1  mrg       goto ab_reduced;
    232      1.1  mrg     }
    233      1.1  mrg 
    234      1.1  mrg   while (bh > 0)
    235      1.1  mrg     {
    236      1.1  mrg       /* Compute (a|b) */
    237      1.1  mrg       while (ah > bh)
    238      1.1  mrg 	{
    239      1.1  mrg 	  sub_ddmmss (ah, al, ah, al, bh, bl);
    240      1.1  mrg 	  if (al == 0)
    241      1.1  mrg 	    {
    242      1.1  mrg 	      count_trailing_zeros (c, ah);
    243      1.1  mrg 	      bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
    244      1.1  mrg 
    245      1.1  mrg 	      al = bl;
    246      1.1  mrg 	      bl = ah >> c;
    247      1.1  mrg 	      ah = bh;
    248      1.1  mrg 
    249      1.1  mrg 	      bit ^= al & bl;
    250      1.1  mrg 	      goto b_reduced;
    251      1.1  mrg 	    }
    252      1.1  mrg 	  count_trailing_zeros (c, al);
    253      1.1  mrg 	  bit ^= (c << 1) & (bl ^ (bl >> 1));
    254      1.1  mrg 	  al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
    255      1.1  mrg 	  ah >>= c;
    256      1.1  mrg 	}
    257      1.1  mrg       if (ah == bh)
    258      1.1  mrg 	goto cancel_hi;
    259      1.1  mrg 
    260      1.1  mrg       if (ah == 0)
    261      1.1  mrg 	{
    262      1.1  mrg 	  bit ^= al & bl;
    263      1.1  mrg 	  MP_LIMB_T_SWAP (al, bl);
    264      1.1  mrg 	  ah = bh;
    265      1.1  mrg 	  break;
    266      1.1  mrg 	}
    267      1.1  mrg 
    268      1.1  mrg       bit ^= al & bl;
    269      1.1  mrg 
    270      1.1  mrg       /* Compute (b|a) */
    271      1.1  mrg       while (bh > ah)
    272      1.1  mrg 	{
    273      1.1  mrg 	  sub_ddmmss (bh, bl, bh, bl, ah, al);
    274      1.1  mrg 	  if (bl == 0)
    275      1.1  mrg 	    {
    276      1.1  mrg 	      count_trailing_zeros (c, bh);
    277      1.1  mrg 	      bit ^= ((GMP_NUMB_BITS + c) << 1) & (al ^ (al >> 1));
    278      1.1  mrg 
    279      1.1  mrg 	      bl = bh >> c;
    280      1.1  mrg 	      bit ^= al & bl;
    281      1.1  mrg 	      goto b_reduced;
    282      1.1  mrg 	    }
    283      1.1  mrg 	  count_trailing_zeros (c, bl);
    284      1.1  mrg 	  bit ^= (c << 1) & (al ^ (al >> 1));
    285      1.1  mrg 	  bl = ((bh << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (bl >> c);
    286      1.1  mrg 	  bh >>= c;
    287      1.1  mrg 	}
    288      1.1  mrg       bit ^= al & bl;
    289      1.1  mrg 
    290      1.1  mrg       /* Compute (a|b) */
    291      1.1  mrg       if (ah == bh)
    292      1.1  mrg 	{
    293      1.1  mrg 	cancel_hi:
    294      1.1  mrg 	  if (al < bl)
    295      1.1  mrg 	    {
    296      1.1  mrg 	      MP_LIMB_T_SWAP (al, bl);
    297      1.1  mrg 	      bit ^= al & bl;
    298      1.1  mrg 	    }
    299      1.1  mrg 	  al -= bl;
    300      1.1  mrg 	  if (al == 0)
    301      1.1  mrg 	    return 0;
    302      1.1  mrg 
    303      1.1  mrg 	  count_trailing_zeros (c, al);
    304      1.1  mrg 	  bit ^= (c << 1) & (bl ^ (bl >> 1));
    305      1.1  mrg 	  al >>= c;
    306      1.1  mrg 
    307      1.1  mrg 	  if (al == 1)
    308      1.1  mrg 	    return 1 - (bit & 2);
    309      1.1  mrg 
    310      1.1  mrg 	  MP_LIMB_T_SWAP (al, bl);
    311      1.1  mrg 	  bit ^= al & bl;
    312      1.1  mrg 	  break;
    313      1.1  mrg 	}
    314      1.1  mrg     }
    315      1.1  mrg 
    316      1.1  mrg  b_reduced:
    317      1.1  mrg   /* Compute (a|b), with b a single limb. */
    318      1.1  mrg   ASSERT (bl & 1);
    319      1.1  mrg 
    320      1.1  mrg   if (bl == 1)
    321      1.1  mrg     /* (a|1) = 1 */
    322      1.1  mrg     return 1 - (bit & 2);
    323      1.1  mrg 
    324      1.1  mrg   while (ah > 0)
    325      1.1  mrg     {
    326      1.1  mrg       ah -= (al < bl);
    327      1.1  mrg       al -= bl;
    328      1.1  mrg       if (al == 0)
    329      1.1  mrg 	{
    330      1.1  mrg 	  if (ah == 0)
    331      1.1  mrg 	    return 0;
    332      1.1  mrg 	  count_trailing_zeros (c, ah);
    333      1.1  mrg 	  bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
    334      1.1  mrg 	  al = ah >> c;
    335      1.1  mrg 	  goto ab_reduced;
    336      1.1  mrg 	}
    337      1.1  mrg       count_trailing_zeros (c, al);
    338      1.1  mrg 
    339      1.1  mrg       al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
    340      1.1  mrg       ah >>= c;
    341      1.1  mrg       bit ^= (c << 1) & (bl ^ (bl >> 1));
    342      1.1  mrg     }
    343      1.1  mrg  ab_reduced:
    344      1.1  mrg   ASSERT (bl & 1);
    345      1.1  mrg   ASSERT (bl > 1);
    346      1.1  mrg 
    347      1.1  mrg   return mpn_jacobi_base (al, bl, bit);
    348      1.1  mrg }
    349      1.1  mrg #else
    350      1.1  mrg #error Unsupported value for JACOBI_2_METHOD
    351      1.1  mrg #endif
    352