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