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 either:
11 * the GNU Lesser General Public License as published by the Free
12 Software Foundation; either version 3 of the License, or (at your
13 option) any later version.
17 * the GNU General Public License as published by the Free Software
18 Foundation; either version 2 of the License, or (at your option) any
21 or both in parallel, as here.
23 The GNU MP Library is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 You should have received copies of the GNU General Public License and the
29 GNU Lesser General Public License along with the GNU MP Library. If not,
30 see https://www.gnu.org/licenses/. */
32 #include "bootstrap.c"
37 int normalization_steps
;
38 mpz_t big_base_inverted
;
42 #define POW2_P(n) (((n) & ((n) - 1)) == 0)
45 ulog2 (unsigned int x
)
48 for (i
= 0; x
!= 0; i
++)
54 generate (int limb_bits
, int nail_bits
, int base
)
56 int numb_bits
= limb_bits
- nail_bits
;
59 mpz_mul_2exp (t
, t
, numb_bits
);
60 mpz_set_ui (big_base
, 1L);
64 mpz_mul_ui (big_base
, big_base
, (long) base
);
65 if (mpz_cmp (big_base
, t
) > 0)
70 mpz_ui_pow_ui (big_base
, (long) base
, (long) chars_per_limb
);
72 normalization_steps
= limb_bits
- mpz_sizeinbase (big_base
, 2);
75 mpz_mul_2exp (t
, t
, 2*limb_bits
- normalization_steps
);
76 mpz_tdiv_q (big_base_inverted
, t
, big_base
);
78 mpz_mul_2exp (t
, t
, limb_bits
);
79 mpz_sub (big_base_inverted
, big_base_inverted
, t
);
83 header (int limb_bits
, int nail_bits
)
85 int numb_bits
= limb_bits
- nail_bits
;
87 generate (limb_bits
, nail_bits
, 10);
89 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
91 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits
);
92 printf ("Error, error, this data is for %d bits\n", numb_bits
);
95 printf ("/* mp_bases[10] data, as literal values */\n");
96 printf ("#define MP_BASES_CHARS_PER_LIMB_10 %d\n", chars_per_limb
);
97 printf ("#define MP_BASES_BIG_BASE_10 CNST_LIMB(0x");
98 mpz_out_str (stdout
, 16, big_base
);
100 printf ("#define MP_BASES_BIG_BASE_INVERTED_10 CNST_LIMB(0x");
101 mpz_out_str (stdout
, 16, big_base_inverted
);
103 printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps
);
109 /* Compute log(2)/log(b) as a fixnum. */
111 mp_2logb (mpz_t r
, int bi
, int prec
)
116 mpz_init_set_ui (t
, 1);
117 mpz_mul_2exp (t
, t
, prec
+EXTRA
);
121 mpz_init_set_ui (two
, 2);
122 mpz_mul_2exp (two
, two
, prec
+EXTRA
);
126 mpz_init_set_ui (b
, bi
);
127 mpz_mul_2exp (b
, b
, prec
+EXTRA
);
129 for (i
= prec
-1; i
>= 0; i
--)
131 mpz_mul_2exp (b
, b
, prec
+EXTRA
);
135 mpz_tdiv_q_2exp (t2
, t2
, prec
+EXTRA
);
137 if (mpz_cmp (t2
, two
) < 0) /* not too large? */
139 mpz_setbit (r
, i
); /* set next less significant bit */
140 mpz_set (t
, t2
); /* new value acceptable */
151 table (int limb_bits
, int nail_bits
)
153 int numb_bits
= limb_bits
- nail_bits
;
155 mpz_t r
, t
, logb2
, log2b
;
162 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
164 printf ("#include \"gmp.h\"\n");
165 printf ("#include \"gmp-impl.h\"\n");
167 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits
);
168 printf ("Error, error, this data is for %d bits\n", numb_bits
);
171 puts ("const struct bases mp_bases[257] =\n{");
172 puts (" /* 0 */ { 0, 0, 0, 0, 0 },");
173 puts (" /* 1 */ { 0, 0, 0, 0, 0 },");
174 for (base
= 2; base
<= 256; base
++)
176 generate (limb_bits
, nail_bits
, base
);
177 mp_2logb (r
, base
, limb_bits
+ 8);
178 mpz_tdiv_q_2exp (logb2
, r
, 8);
180 mpz_mul_2exp (t
, t
, 2*limb_bits
+ 5);
181 mpz_sub_ui (t
, t
, 1);
182 mpz_add_ui (r
, r
, 1);
183 mpz_tdiv_q (log2b
, t
, r
);
185 printf (" /* %3u */ { ", base
);
188 mpz_set_ui (big_base
, ulog2 (base
) - 1);
189 mpz_set_ui (big_base_inverted
, 0);
192 printf ("%u,", chars_per_limb
);
193 printf (" CNST_LIMB(0x");
194 mpz_out_str (stdout
, 16, logb2
);
195 printf ("), CNST_LIMB(0x");
196 mpz_out_str (stdout
, 16, log2b
);
197 printf ("), CNST_LIMB(0x");
198 mpz_out_str (stdout
, 16, big_base
);
199 printf ("), CNST_LIMB(0x");
200 mpz_out_str (stdout
, 16, big_base_inverted
);
214 main (int argc
, char **argv
)
216 int limb_bits
, nail_bits
;
219 mpz_init (big_base_inverted
);
224 fprintf (stderr
, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
228 limb_bits
= atoi (argv
[2]);
229 nail_bits
= atoi (argv
[3]);
233 || nail_bits
>= limb_bits
)
235 fprintf (stderr
, "Invalid limb/nail bits: %d %d\n",
236 limb_bits
, nail_bits
);
240 if (strcmp (argv
[1], "header") == 0)
241 header (limb_bits
, nail_bits
);
242 else if (strcmp (argv
[1], "table") == 0)
243 table (limb_bits
, nail_bits
);
246 fprintf (stderr
, "Invalid header/table choice: %s\n", argv
[1]);