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