github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/gen-bases.c (about)

     1  /* Generate mp_bases data.
     2  
     3  Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004, 2011, 2012 Free Software
     4  Foundation, 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 either:
    10  
    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.
    14  
    15  or
    16  
    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
    19      later version.
    20  
    21  or both in parallel, as here.
    22  
    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
    26  for more details.
    27  
    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/.  */
    31  
    32  #include "bootstrap.c"
    33  
    34  
    35  int    chars_per_limb;
    36  mpz_t  big_base;
    37  int    normalization_steps;
    38  mpz_t  big_base_inverted;
    39  
    40  mpz_t  t;
    41  
    42  #define POW2_P(n)  (((n) & ((n) - 1)) == 0)
    43  
    44  unsigned int
    45  ulog2 (unsigned int x)
    46  {
    47    unsigned int i;
    48    for (i = 0;  x != 0;  i++)
    49      x >>= 1;
    50    return i;
    51  }
    52  
    53  void
    54  generate (int limb_bits, int nail_bits, int base)
    55  {
    56    int  numb_bits = limb_bits - nail_bits;
    57  
    58    mpz_set_ui (t, 1L);
    59    mpz_mul_2exp (t, t, numb_bits);
    60    mpz_set_ui (big_base, 1L);
    61    chars_per_limb = 0;
    62    for (;;)
    63      {
    64        mpz_mul_ui (big_base, big_base, (long) base);
    65        if (mpz_cmp (big_base, t) > 0)
    66          break;
    67        chars_per_limb++;
    68      }
    69  
    70    mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb);
    71  
    72    normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2);
    73  
    74    mpz_set_ui (t, 1L);
    75    mpz_mul_2exp (t, t, 2*limb_bits - normalization_steps);
    76    mpz_tdiv_q (big_base_inverted, t, big_base);
    77    mpz_set_ui (t, 1L);
    78    mpz_mul_2exp (t, t, limb_bits);
    79    mpz_sub (big_base_inverted, big_base_inverted, t);
    80  }
    81  
    82  void
    83  header (int limb_bits, int nail_bits)
    84  {
    85    int  numb_bits = limb_bits - nail_bits;
    86  
    87    generate (limb_bits, nail_bits, 10);
    88  
    89    printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
    90    printf ("\n");
    91    printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
    92    printf ("Error, error, this data is for %d bits\n", numb_bits);
    93    printf ("#endif\n");
    94    printf ("\n");
    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);
    99    printf (")\n");
   100    printf ("#define MP_BASES_BIG_BASE_INVERTED_10   CNST_LIMB(0x");
   101    mpz_out_str (stdout, 16, big_base_inverted);
   102    printf (")\n");
   103    printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps);
   104  }
   105  
   106  
   107  #define EXTRA 16
   108  
   109  /* Compute log(2)/log(b) as a fixnum. */
   110  void
   111  mp_2logb (mpz_t r, int bi, int prec)
   112  {
   113    mpz_t t, t2, two, b;
   114    int i;
   115  
   116    mpz_init_set_ui (t, 1);
   117    mpz_mul_2exp (t, t, prec+EXTRA);
   118  
   119    mpz_init (t2);
   120  
   121    mpz_init_set_ui (two, 2);
   122    mpz_mul_2exp (two, two, prec+EXTRA);
   123  
   124    mpz_set_ui (r, 0);
   125  
   126    mpz_init_set_ui (b, bi);
   127    mpz_mul_2exp (b, b, prec+EXTRA);
   128  
   129    for (i = prec-1; i >= 0; i--)
   130      {
   131        mpz_mul_2exp (b, b, prec+EXTRA);
   132        mpz_sqrt (b, b);
   133  
   134        mpz_mul (t2, t, b);
   135        mpz_tdiv_q_2exp (t2, t2, prec+EXTRA);
   136  
   137        if (mpz_cmp (t2, two) < 0)	/* not too large? */
   138  	{
   139  	  mpz_setbit (r, i);		/* set next less significant bit */
   140  	  mpz_set (t, t2);		/* new value acceptable */
   141  	}
   142      }
   143  
   144    mpz_clear (t);
   145    mpz_clear (t2);
   146    mpz_clear (two);
   147    mpz_clear (b);
   148  }
   149  
   150  void
   151  table (int limb_bits, int nail_bits)
   152  {
   153    int  numb_bits = limb_bits - nail_bits;
   154    int  base;
   155    mpz_t r, t, logb2, log2b;
   156  
   157    mpz_init (r);
   158    mpz_init (t);
   159    mpz_init (logb2);
   160    mpz_init (log2b);
   161  
   162    printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
   163    printf ("\n");
   164    printf ("#include \"gmp.h\"\n");
   165    printf ("#include \"gmp-impl.h\"\n");
   166    printf ("\n");
   167    printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
   168    printf ("Error, error, this data is for %d bits\n", numb_bits);
   169    printf ("#endif\n");
   170    printf ("\n");
   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++)
   175      {
   176        generate (limb_bits, nail_bits, base);
   177        mp_2logb (r, base, limb_bits + 8);
   178        mpz_tdiv_q_2exp (logb2, r, 8);
   179        mpz_set_ui (t, 1);
   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);
   184  
   185        printf ("  /* %3u */ { ", base);
   186        if (POW2_P (base))
   187  	{
   188            mpz_set_ui (big_base, ulog2 (base) - 1);
   189  	  mpz_set_ui (big_base_inverted, 0);
   190  	}
   191  
   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);
   201        printf (") },\n");
   202      }
   203  
   204    puts ("};");
   205  
   206    mpz_clear (r);
   207    mpz_clear (t);
   208    mpz_clear (logb2);
   209    mpz_clear (log2b);
   210  
   211  }
   212  
   213  int
   214  main (int argc, char **argv)
   215  {
   216    int  limb_bits, nail_bits;
   217  
   218    mpz_init (big_base);
   219    mpz_init (big_base_inverted);
   220    mpz_init (t);
   221  
   222    if (argc != 4)
   223      {
   224        fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
   225        exit (1);
   226      }
   227  
   228    limb_bits = atoi (argv[2]);
   229    nail_bits = atoi (argv[3]);
   230  
   231    if (limb_bits <= 0
   232        || nail_bits < 0
   233        || nail_bits >= limb_bits)
   234      {
   235        fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
   236                 limb_bits, nail_bits);
   237        exit (1);
   238      }
   239  
   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);
   244    else
   245      {
   246        fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);
   247        exit (1);
   248      }
   249  
   250    return 0;
   251  }