tizen 2.3 release
[external/gmp.git] / gen-bases.c
1 /* Generate mp_bases data.
2
3 Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004 Free Software Foundation,
4 Inc.
5
6 This file is part of the GNU MP Library.
7
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 2.1 of the License, or (at your
11 option) any later version.
12
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.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include <math.h>
24
25 #include "dumbmp.c"
26
27
28 int    chars_per_limb;
29 double chars_per_bit_exactly;
30 mpz_t  big_base;
31 int    normalization_steps;
32 mpz_t  big_base_inverted;
33
34 mpz_t  t;
35
36 #define POW2_P(n)  (((n) & ((n) - 1)) == 0)
37
38 unsigned int
39 ulog2 (unsigned int x)
40 {
41   unsigned int i;
42   for (i = 0;  x != 0;  i++)
43     x >>= 1;
44   return i;
45 }
46
47 void
48 generate (int limb_bits, int nail_bits, int base)
49 {
50   int  numb_bits = limb_bits - nail_bits;
51
52   mpz_set_ui (t, 1L);
53   mpz_mul_2exp (t, t, numb_bits);
54   mpz_set_ui (big_base, 1L);
55   chars_per_limb = 0;
56   for (;;)
57     {
58       mpz_mul_ui (big_base, big_base, (long) base);
59       if (mpz_cmp (big_base, t) > 0)
60         break;
61       chars_per_limb++;
62     }
63
64   chars_per_bit_exactly = 0.69314718055994530942 / log ((double) base);
65
66   mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb);
67
68   normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2);
69
70   mpz_set_ui (t, 1L);
71   mpz_mul_2exp (t, t, 2*limb_bits - normalization_steps);
72   mpz_tdiv_q (big_base_inverted, t, big_base);
73   mpz_set_ui (t, 1L);
74   mpz_mul_2exp (t, t, limb_bits);
75   mpz_sub (big_base_inverted, big_base_inverted, t);
76 }
77
78 void
79 header (int limb_bits, int nail_bits)
80 {
81   int  numb_bits = limb_bits - nail_bits;
82
83   generate (limb_bits, nail_bits, 10);
84
85   printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
86   printf ("\n");
87   printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
88   printf ("Error, error, this data is for %d bits\n", numb_bits);
89   printf ("#endif\n");
90   printf ("\n");
91   printf ("/* mp_bases[10] data, as literal values */\n");
92   printf ("#define MP_BASES_CHARS_PER_LIMB_10      %d\n", chars_per_limb);
93   printf ("#define MP_BASES_BIG_BASE_10            CNST_LIMB(0x");
94   mpz_out_str (stdout, 16, big_base);
95   printf (")\n");
96   printf ("#define MP_BASES_BIG_BASE_INVERTED_10   CNST_LIMB(0x");
97   mpz_out_str (stdout, 16, big_base_inverted);
98   printf (")\n");
99   printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps);
100 }
101
102 void
103 table (int limb_bits, int nail_bits)
104 {
105   int  numb_bits = limb_bits - nail_bits;
106   int  base;
107
108   printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
109   printf ("\n");
110   printf ("#include \"gmp.h\"\n");
111   printf ("#include \"gmp-impl.h\"\n");
112   printf ("\n");
113   printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
114   printf ("Error, error, this data is for %d bits\n", numb_bits);
115   printf ("#endif\n");
116   printf ("\n");
117   puts ("const struct bases mp_bases[257] =\n{");
118   puts ("  /*   0 */ { 0, 0.0, 0 },");
119   puts ("  /*   1 */ { 0, 1e37, 0 },");
120   for (base = 2; base <= 256; base++)
121     {
122       generate (limb_bits, nail_bits, base);
123
124       printf ("  /* %3u */ { ", base);
125       if (POW2_P (base))
126         {
127           printf ("%u, %.16f, 0x%x },\n",
128                   chars_per_limb, chars_per_bit_exactly, ulog2 (base) - 1);
129         }
130       else
131         {
132           printf ("%u, %.16f, CNST_LIMB(0x",
133                   chars_per_limb, chars_per_bit_exactly);
134           mpz_out_str (stdout, 16, big_base);
135           printf ("), CNST_LIMB(0x");
136           mpz_out_str (stdout, 16, big_base_inverted);
137           printf (") },\n");
138         }
139     }
140
141   puts ("};");
142 }
143
144 int
145 main (int argc, char **argv)
146 {
147   int  limb_bits, nail_bits;
148
149   mpz_init (big_base);
150   mpz_init (big_base_inverted);
151   mpz_init (t);
152
153   if (argc != 4)
154     {
155       fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
156       exit (1);
157     }
158
159   limb_bits = atoi (argv[2]);
160   nail_bits = atoi (argv[3]);
161
162   if (limb_bits <= 0
163       || nail_bits < 0
164       || nail_bits >= limb_bits)
165     {
166       fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
167                limb_bits, nail_bits);
168       exit (1);
169     }
170
171   if (strcmp (argv[1], "header") == 0)
172     header (limb_bits, nail_bits);
173   else if (strcmp (argv[1], "table") == 0)
174     table (limb_bits, nail_bits);
175   else
176     {
177       fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);
178       exit (1);
179     }
180
181   return 0;
182 }
183