1 /* Generate mp_bases data.
3 Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004, 2011, 2012 Free Software
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 #include "bootstrap.c"
26 int normalization_steps;
27 mpz_t big_base_inverted;
31 #define POW2_P(n) (((n) & ((n) - 1)) == 0)
34 ulog2 (unsigned int x)
37 for (i = 0; x != 0; i++)
43 generate (int limb_bits, int nail_bits, int base)
45 int numb_bits = limb_bits - nail_bits;
48 mpz_mul_2exp (t, t, numb_bits);
49 mpz_set_ui (big_base, 1L);
53 mpz_mul_ui (big_base, big_base, (long) base);
54 if (mpz_cmp (big_base, t) > 0)
59 mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb);
61 normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2);
64 mpz_mul_2exp (t, t, 2*limb_bits - normalization_steps);
65 mpz_tdiv_q (big_base_inverted, t, big_base);
67 mpz_mul_2exp (t, t, limb_bits);
68 mpz_sub (big_base_inverted, big_base_inverted, t);
72 header (int limb_bits, int nail_bits)
74 int numb_bits = limb_bits - nail_bits;
76 generate (limb_bits, nail_bits, 10);
78 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
80 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
81 printf ("Error, error, this data is for %d bits\n", numb_bits);
84 printf ("/* mp_bases[10] data, as literal values */\n");
85 printf ("#define MP_BASES_CHARS_PER_LIMB_10 %d\n", chars_per_limb);
86 printf ("#define MP_BASES_BIG_BASE_10 CNST_LIMB(0x");
87 mpz_out_str (stdout, 16, big_base);
89 printf ("#define MP_BASES_BIG_BASE_INVERTED_10 CNST_LIMB(0x");
90 mpz_out_str (stdout, 16, big_base_inverted);
92 printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps);
98 /* Compute log(2)/log(b) as a fixnum. */
100 mp_2logb (mpz_t r, int bi, int prec)
105 mpz_init_set_ui (t, 1);
106 mpz_mul_2exp (t, t, prec+EXTRA);
110 mpz_init_set_ui (two, 2);
111 mpz_mul_2exp (two, two, prec+EXTRA);
115 mpz_init_set_ui (b, bi);
116 mpz_mul_2exp (b, b, prec+EXTRA);
118 for (i = prec-1; i >= 0; i--)
120 mpz_mul_2exp (b, b, prec+EXTRA);
124 mpz_tdiv_q_2exp (t2, t2, prec+EXTRA);
126 if (mpz_cmp (t2, two) < 0) /* not too large? */
128 mpz_setbit (r, i); /* set next less significant bit */
129 mpz_set (t, t2); /* new value acceptable */
140 table (int limb_bits, int nail_bits)
142 int numb_bits = limb_bits - nail_bits;
144 mpz_t r, t, logb2, log2b;
151 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
153 printf ("#include \"gmp.h\"\n");
154 printf ("#include \"gmp-impl.h\"\n");
156 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
157 printf ("Error, error, this data is for %d bits\n", numb_bits);
160 puts ("const struct bases mp_bases[257] =\n{");
161 puts (" /* 0 */ { 0, 0, 0, 0, 0 },");
162 puts (" /* 1 */ { 0, 0, 0, 0, 0 },");
163 for (base = 2; base <= 256; base++)
165 generate (limb_bits, nail_bits, base);
166 mp_2logb (r, base, limb_bits + 8);
167 mpz_tdiv_q_2exp (logb2, r, 8);
169 mpz_mul_2exp (t, t, 2*limb_bits + 5);
170 mpz_sub_ui (t, t, 1);
171 mpz_add_ui (r, r, 1);
172 mpz_tdiv_q (log2b, t, r);
174 printf (" /* %3u */ { ", base);
177 mpz_set_ui (big_base, ulog2 (base) - 1);
178 mpz_set_ui (big_base_inverted, 0);
181 printf ("%u,", chars_per_limb);
182 printf (" CNST_LIMB(0x");
183 mpz_out_str (stdout, 16, logb2);
184 printf ("), CNST_LIMB(0x");
185 mpz_out_str (stdout, 16, log2b);
186 printf ("), CNST_LIMB(0x");
187 mpz_out_str (stdout, 16, big_base);
188 printf ("), CNST_LIMB(0x");
189 mpz_out_str (stdout, 16, big_base_inverted);
203 main (int argc, char **argv)
205 int limb_bits, nail_bits;
208 mpz_init (big_base_inverted);
213 fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
217 limb_bits = atoi (argv[2]);
218 nail_bits = atoi (argv[3]);
222 || nail_bits >= limb_bits)
224 fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
225 limb_bits, nail_bits);
229 if (strcmp (argv[1], "header") == 0)
230 header (limb_bits, nail_bits);
231 else if (strcmp (argv[1], "table") == 0)
232 table (limb_bits, nail_bits);
235 fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);