dma(8): Use FALLTHROUGH consistently.
[dragonfly.git] / contrib / gmp / gen-trialdivtab.c
blob708253926fcbf2c00b5c3d19db1cdb14793279ae
1 /* gen-trialdivtab.c
3 Contributed to the GNU project by Torbjorn Granlund.
5 Copyright 2009 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 the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
14 The GNU MP Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23 Generate tables for fast, division-free trial division for GMP.
25 There is one main table, ptab. It contains primes, multiplied together, and
26 several types of pre-computed inverses. It refers to tables of the type
27 dtab, via the last two indices. That table contains the individual primes in
28 the range, except that the primes are not actually included in the table (see
29 the P macro; it sneakingly excludes the primes themselves). Instead, the
30 dtab tables contains tuples for each prime (modular-inverse, limit) used for
31 divisibility checks.
33 This interface is not intended for division of very many primes, since then
34 other algorithms apply.
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include "dumbmp.c"
41 int sumspills (mpz_t, mpz_t *, int);
42 void mpn_mod_1s_4p_cps (mpz_t [7], mpz_t);
44 int limb_bits;
46 mpz_t B;
48 int
49 main (int argc, char *argv[])
51 unsigned long t, p;
52 mpz_t ppp, acc, inv, gmp_numb_max, tmp, Bhalf;
53 mpz_t pre[7];
54 int i;
55 int start_p, end_p, interval_start, interval_end, omitted_p;
56 char *endtok;
57 int stop;
58 int np, start_idx;
60 if (argc < 2)
62 fprintf (stderr, "usage: %s bits endprime\n", argv[0]);
63 exit (1);
66 limb_bits = atoi (argv[1]);
68 end_p = 1290; /* default end prime */
69 if (argc == 3)
70 end_p = atoi (argv[2]);
72 printf ("#if GMP_LIMB_BITS != %d\n", limb_bits);
73 printf ("#error This table is for GMP_LIMB_BITS = %d\n", limb_bits);
74 printf ("#endif\n\n");
76 printf ("#if GMP_NAIL_BITS != 0\n");
77 printf ("#error This table does not support nails\n");
78 printf ("#endif\n\n");
80 for (i = 0; i < 7; i++)
81 mpz_init (pre[i]);
83 mpz_init_set_ui (gmp_numb_max, 1);
84 mpz_mul_2exp (gmp_numb_max, gmp_numb_max, limb_bits);
85 mpz_sub_ui (gmp_numb_max, gmp_numb_max, 1);
87 mpz_init (tmp);
88 mpz_init (inv);
90 mpz_init_set_ui (B, 1); mpz_mul_2exp (B, B, limb_bits);
91 mpz_init_set_ui (Bhalf, 1); mpz_mul_2exp (Bhalf, Bhalf, limb_bits - 1);
93 start_p = 3;
95 mpz_init_set_ui (ppp, 1);
96 mpz_init (acc);
97 interval_start = start_p;
98 omitted_p = 3;
99 interval_end = 0;
101 printf ("static struct gmp_primes_dtab gmp_primes_dtab[] = {\n");
103 for (t = start_p; t <= end_p; t += 2)
105 if (! isprime (t))
106 continue;
108 mpz_mul_ui (acc, ppp, t);
109 stop = mpz_cmp (acc, Bhalf) >= 0;
110 if (!stop)
112 mpn_mod_1s_4p_cps (pre, acc);
113 stop = sumspills (acc, pre + 2, 5);
116 if (stop)
118 for (p = interval_start; p <= interval_end; p += 2)
120 if (! isprime (p))
121 continue;
123 printf (" P(%d,", (int) p);
124 mpz_invert_ui_2exp (inv, p, limb_bits);
125 printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, inv); printf ("),");
127 mpz_tdiv_q_ui (tmp, gmp_numb_max, p);
128 printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, tmp);
129 printf (")),\n");
131 mpz_set_ui (ppp, t);
132 interval_start = t;
133 omitted_p = t;
135 else
137 mpz_set (ppp, acc);
139 interval_end = t;
141 printf (" P(0,0,0)\n};\n");
144 printf ("static struct gmp_primes_ptab gmp_primes_ptab[] = {\n");
146 endtok = "";
148 mpz_set_ui (ppp, 1);
149 interval_start = start_p;
150 interval_end = 0;
151 np = 0;
152 start_idx = 0;
153 for (t = start_p; t <= end_p; t += 2)
155 if (! isprime (t))
156 continue;
158 mpz_mul_ui (acc, ppp, t);
160 stop = mpz_cmp (acc, Bhalf) >= 0;
161 if (!stop)
163 mpn_mod_1s_4p_cps (pre, acc);
164 stop = sumspills (acc, pre + 2, 5);
167 if (stop)
169 mpn_mod_1s_4p_cps (pre, ppp);
170 printf ("%s", endtok);
171 printf (" {CNST_LIMB(0x"); mpz_out_str (stdout, 16, ppp);
172 printf ("),{CNST_LIMB(0x"); mpz_out_str (stdout, 16, pre[0]);
173 printf ("),%d", (int) PTR(pre[1])[0]);
174 for (i = 0; i < 5; i++)
176 printf (",");
177 printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, pre[2 + i]);
178 printf (")");
180 printf ("},");
181 printf ("%d,", start_idx);
182 printf ("%d}", np - start_idx);
184 endtok = ",\n";
185 mpz_set_ui (ppp, t);
186 interval_start = t;
187 start_idx = np;
189 else
191 mpz_set (ppp, acc);
193 interval_end = t;
194 np++;
196 printf ("\n};\n");
198 printf ("#define SMALLEST_OMITTED_PRIME %d\n", (int) omitted_p);
200 return 0;
203 unsigned long
204 mpz_log2 (mpz_t x)
206 mpz_t y;
207 unsigned long cnt;
209 mpz_init (y);
210 mpz_set (y, x);
211 cnt = 0;
212 while (mpz_sgn (y) != 0)
214 mpz_tdiv_q_2exp (y, y, 1);
215 cnt++;
217 mpz_clear (y);
219 return cnt;
222 void
223 mpn_mod_1s_4p_cps (mpz_t cps[7], mpz_t bparm)
225 mpz_t b, bi;
226 mpz_t B1modb, B2modb, B3modb, B4modb, B5modb;
227 mpz_t t;
228 int cnt;
230 mpz_init_set (b, bparm);
232 cnt = limb_bits - mpz_log2 (b);
234 mpz_init (bi);
235 mpz_init (t);
236 mpz_init (B1modb);
237 mpz_init (B2modb);
238 mpz_init (B3modb);
239 mpz_init (B4modb);
240 mpz_init (B5modb);
242 mpz_set_ui (t, 1);
243 mpz_mul_2exp (t, t, limb_bits - cnt);
244 mpz_sub (t, t, b);
245 mpz_mul_2exp (t, t, limb_bits);
246 mpz_tdiv_q (bi, t, b); /* bi = B^2/b, except msb */
248 mpz_set_ui (t, 1);
249 mpz_mul_2exp (t, t, limb_bits); /* t = B */
250 mpz_tdiv_r (B1modb, t, b);
252 mpz_mul_2exp (t, B1modb, limb_bits);
253 mpz_tdiv_r (B2modb, t, b);
255 mpz_mul_2exp (t, B2modb, limb_bits);
256 mpz_tdiv_r (B3modb, t, b);
258 mpz_mul_2exp (t, B3modb, limb_bits);
259 mpz_tdiv_r (B4modb, t, b);
261 mpz_mul_2exp (t, B4modb, limb_bits);
262 mpz_tdiv_r (B5modb, t, b);
264 mpz_set (cps[0], bi);
265 mpz_set_ui (cps[1], cnt);
266 mpz_tdiv_q_2exp (cps[2], B1modb, 0);
267 mpz_tdiv_q_2exp (cps[3], B2modb, 0);
268 mpz_tdiv_q_2exp (cps[4], B3modb, 0);
269 mpz_tdiv_q_2exp (cps[5], B4modb, 0);
270 mpz_tdiv_q_2exp (cps[6], B5modb, 0);
272 mpz_clear (b);
273 mpz_clear (bi);
274 mpz_clear (t);
275 mpz_clear (B1modb);
276 mpz_clear (B2modb);
277 mpz_clear (B3modb);
278 mpz_clear (B4modb);
279 mpz_clear (B5modb);
283 sumspills (mpz_t ppp, mpz_t *a, int n)
285 mpz_t s;
286 int i, ret;
288 mpz_init_set (s, a[0]);
290 for (i = 1; i < n; i++)
292 mpz_add (s, s, a[i]);
294 ret = mpz_cmp (s, B) >= 0;
295 mpz_clear (s);
297 return ret;