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