Fix strtod rounding (bug 3479).
[platform/upstream/glibc.git] / stdlib / gen-fpioconst.c
1 /* Generate data for fpioconst.c.
2    Copyright (C) 2012 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <inttypes.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <gmp.h>
24
25 int
26 main (void)
27 {
28   FILE *out32 = fopen ("fpioconst-32", "w");
29   if (out32 == NULL)
30     abort ();
31   FILE *out64 = fopen ("fpioconst-64", "w");
32   if (out64 == NULL)
33     abort ();
34   FILE *outtable = fopen ("fpioconst-table", "w");
35   if (outtable == NULL)
36     abort ();
37   mpz_t p;
38   mpz_init (p);
39   for (int i = 0; i <= 14; i++)
40     {
41       int j = 1 << i;
42       mpz_ui_pow_ui (p, 10, j - 1);
43       int exp_m = mpz_sizeinbase (p, 2);
44       mpz_ui_pow_ui (p, 10, j);
45       int exp_p = mpz_sizeinbase (p, 2);
46       int size32 = 2 + (exp_p + 31) / 32;
47       int size64 = 1 + (exp_p + 63) / 64;
48       uint32_t data32[size32];
49       uint64_t data64[size64];
50       memset (data32, 0, sizeof data32);
51       memset (data64, 0, sizeof data64);
52       mpz_export (data32 + 2, NULL, -1, 4, 0, 0, p);
53       mpz_export (data64 + 1, NULL, -1, 8, 0, 0, p);
54       if (i == 0)
55         {
56           fprintf (out32, "#define TENS_P%d_IDX\t0\n", i);
57           fprintf (out64, "#define TENS_P%d_IDX\t0\n", i);
58         }
59       else
60         {
61           fprintf (out32, "#define TENS_P%d_IDX\t"
62                    "(TENS_P%d_IDX + TENS_P%d_SIZE)\n",
63                    i, i - 1, i - 1);
64           fprintf (out64, "#define TENS_P%d_IDX\t"
65                    "(TENS_P%d_IDX + TENS_P%d_SIZE)\n",
66                    i, i - 1, i - 1);
67         }
68       fprintf (out32, "#define TENS_P%d_SIZE\t%d\n", i, size32);
69       fprintf (out64, "#define TENS_P%d_SIZE\t%d\n", i, size64);
70       for (int k = 0; k < size32; k++)
71         {
72           if (k == 0)
73             fprintf (out32, "  [TENS_P%d_IDX] = ", i);
74           else if (k % 6 == 5)
75             fprintf (out32, "\n  ");
76           else
77             fprintf (out32, " ");
78           fprintf (out32, "0x%08"PRIx32",", data32[k]);
79         }
80       for (int k = 0; k < size64; k++)
81         {
82           if (k == 0)
83             fprintf (out64, "  [TENS_P%d_IDX] = ", i);
84           else if (k % 3 == 2)
85             fprintf (out64, "\n  ");
86           else
87             fprintf (out64, " ");
88           fprintf (out64, "0x%016"PRIx64"ull,", data64[k]);
89         }
90       fprintf (out32, "\n\n");
91       fprintf (out64, "\n\n");
92       const char *t = (i >= 10 ? "\t" : "\t\t");
93       if (i == 0)
94         fprintf (outtable, "  { TENS_P%d_IDX, TENS_P%d_SIZE,%s%d,\t      },\n",
95                  i, i, t, exp_p);
96       else
97         fprintf (outtable, "  { TENS_P%d_IDX, TENS_P%d_SIZE,%s%d,\t%5d },\n",
98                  i, i, t, exp_p, exp_m);
99     }
100   if (fclose (out32) != 0)
101     abort ();
102   if (fclose (out64) != 0)
103     abort ();
104   if (fclose (outtable) != 0)
105     abort ();
106   return 0;
107 }