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