3 Contributed to the GNU project by Torbjorn Granlund.
5 Copyright 2009, 2012, 2013 Free Software Foundation, Inc.
7 This file is part of the GNU MP Library.
9 The GNU MP Library is free software; you can redistribute it and/or modify
10 it under the terms of either:
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
18 * the GNU General Public License as published by the Free Software
19 Foundation; either version 2 of the License, or (at your option) any
22 or both in parallel, as here.
24 The GNU MP Library is distributed in the hope that it will be useful, but
25 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 You should have received copies of the GNU General Public License and the
30 GNU Lesser General Public License along with the GNU MP Library. If not,
31 see https://www.gnu.org/licenses/. */
34 Generate tables for fast, division-free trial division for GMP.
36 There is one main table, ptab. It contains primes, multiplied together, and
37 several types of pre-computed inverses. It refers to tables of the type
38 dtab, via the last two indices. That table contains the individual primes in
39 the range, except that the primes are not actually included in the table (see
40 the P macro; it sneakingly excludes the primes themselves). Instead, the
41 dtab tables contains tuples for each prime (modular-inverse, limit) used for
44 This interface is not intended for division of very many primes, since then
45 other algorithms apply.
50 #include "bootstrap.c"
52 int sumspills (mpz_t
, mpz_t
*, int);
53 void mpn_mod_1s_4p_cps (mpz_t
[7], mpz_t
);
60 main (int argc
, char *argv
[])
63 mpz_t ppp
, acc
, inv
, gmp_numb_max
, tmp
, Bhalf
;
66 int start_p
, end_p
, interval_start
, interval_end
, omitted_p
;
73 fprintf (stderr
, "usage: %s bits endprime\n", argv
[0]);
77 limb_bits
= atoi (argv
[1]);
79 end_p
= 1290; /* default end prime */
81 end_p
= atoi (argv
[2]);
83 printf ("#if GMP_LIMB_BITS != %d\n", limb_bits
);
84 printf ("#error This table is for GMP_LIMB_BITS = %d\n", limb_bits
);
85 printf ("#endif\n\n");
87 printf ("#if GMP_NAIL_BITS != 0\n");
88 printf ("#error This table does not support nails\n");
89 printf ("#endif\n\n");
91 for (i
= 0; i
< 7; i
++)
94 mpz_init_set_ui (gmp_numb_max
, 1);
95 mpz_mul_2exp (gmp_numb_max
, gmp_numb_max
, limb_bits
);
96 mpz_sub_ui (gmp_numb_max
, gmp_numb_max
, 1);
101 mpz_init_set_ui (B
, 1); mpz_mul_2exp (B
, B
, limb_bits
);
102 mpz_init_set_ui (Bhalf
, 1); mpz_mul_2exp (Bhalf
, Bhalf
, limb_bits
- 1);
106 mpz_init_set_ui (ppp
, 1);
108 interval_start
= start_p
;
112 /* printf ("static struct gmp_primes_dtab gmp_primes_dtab[] = {\n"); */
114 printf ("#ifdef WANT_dtab\n");
116 for (t
= start_p
; t
<= end_p
; t
+= 2)
121 mpz_mul_ui (acc
, ppp
, t
);
122 stop
= mpz_cmp (acc
, Bhalf
) >= 0;
125 mpn_mod_1s_4p_cps (pre
, acc
);
126 stop
= sumspills (acc
, pre
+ 2, 5);
131 for (p
= interval_start
; p
<= interval_end
; p
+= 2)
136 printf (" P(%d,", (int) p
);
137 mpz_invert_ui_2exp (inv
, p
, limb_bits
);
138 printf ("CNST_LIMB(0x"); mpz_out_str (stdout
, 16, inv
); printf ("),");
140 mpz_tdiv_q_ui (tmp
, gmp_numb_max
, p
);
141 printf ("CNST_LIMB(0x"); mpz_out_str (stdout
, 16, tmp
);
154 printf ("#define SMALLEST_OMITTED_PRIME %d\n", (int) omitted_p
);
157 printf ("#ifdef WANT_ptab\n");
159 /* printf ("static struct gmp_primes_ptab gmp_primes_ptab[] = {\n"); */
164 interval_start
= start_p
;
168 for (t
= start_p
; t
<= end_p
; t
+= 2)
173 mpz_mul_ui (acc
, ppp
, t
);
175 stop
= mpz_cmp (acc
, Bhalf
) >= 0;
178 mpn_mod_1s_4p_cps (pre
, acc
);
179 stop
= sumspills (acc
, pre
+ 2, 5);
184 mpn_mod_1s_4p_cps (pre
, ppp
);
185 printf ("%s", endtok
);
186 printf (" {CNST_LIMB(0x"); mpz_out_str (stdout
, 16, ppp
);
187 printf ("),{CNST_LIMB(0x"); mpz_out_str (stdout
, 16, pre
[0]);
188 printf ("),%d", (int) PTR(pre
[1])[0]);
189 for (i
= 0; i
< 5; i
++)
192 printf ("CNST_LIMB(0x"); mpz_out_str (stdout
, 16, pre
[2 + i
]);
196 printf ("%d,", start_idx
);
197 printf ("%d}", np
- start_idx
);
221 return mpz_sgn (x
) ? mpz_sizeinbase (x
, 2) : 0;
225 mpn_mod_1s_4p_cps (mpz_t cps
[7], mpz_t bparm
)
228 mpz_t B1modb
, B2modb
, B3modb
, B4modb
, B5modb
;
232 mpz_init_set (b
, bparm
);
234 cnt
= limb_bits
- mpz_log2 (b
);
245 mpz_mul_2exp (t
, t
, limb_bits
- cnt
);
247 mpz_mul_2exp (t
, t
, limb_bits
);
248 mpz_tdiv_q (bi
, t
, b
); /* bi = B^2/b, except msb */
251 mpz_mul_2exp (t
, t
, limb_bits
); /* t = B */
252 mpz_tdiv_r (B1modb
, t
, b
);
254 mpz_mul_2exp (t
, B1modb
, limb_bits
);
255 mpz_tdiv_r (B2modb
, t
, b
);
257 mpz_mul_2exp (t
, B2modb
, limb_bits
);
258 mpz_tdiv_r (B3modb
, t
, b
);
260 mpz_mul_2exp (t
, B3modb
, limb_bits
);
261 mpz_tdiv_r (B4modb
, t
, b
);
263 mpz_mul_2exp (t
, B4modb
, limb_bits
);
264 mpz_tdiv_r (B5modb
, t
, b
);
266 mpz_set (cps
[0], bi
);
267 mpz_set_ui (cps
[1], cnt
);
268 mpz_tdiv_q_2exp (cps
[2], B1modb
, 0);
269 mpz_tdiv_q_2exp (cps
[3], B2modb
, 0);
270 mpz_tdiv_q_2exp (cps
[4], B3modb
, 0);
271 mpz_tdiv_q_2exp (cps
[5], B4modb
, 0);
272 mpz_tdiv_q_2exp (cps
[6], B5modb
, 0);
285 sumspills (mpz_t ppp
, mpz_t
*a
, int n
)
290 mpz_init_set (s
, a
[0]);
292 for (i
= 1; i
< n
; i
++)
294 mpz_add (s
, s
, a
[i
]);
296 ret
= mpz_cmp (s
, B
) >= 0;