github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpn/t-aors_1.c (about)

     1  /* Test mpn_add_1 and mpn_sub_1.
     2  
     3  Copyright 2001, 2002 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <stdio.h>
    21  #include <stdlib.h>
    22  
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  
    28  #define M      GMP_NUMB_MAX
    29  #define ASIZE  10
    30  #define MAGIC  0x1234
    31  
    32  #define SETUP()                         \
    33    do {                                  \
    34      refmpn_random (got, data[i].size);  \
    35      got[data[i].size] = MAGIC;          \
    36    } while (0)
    37  
    38  #define SETUP_INPLACE()                                 \
    39    do {                                                  \
    40      refmpn_copyi (got, data[i].src, data[i].size);      \
    41      got[data[i].size] = MAGIC;                          \
    42    } while (0)
    43  
    44  #define VERIFY(name)                            \
    45    do {                                          \
    46      verify (name, i, data[i].src, data[i].n,    \
    47              got_c, data[i].want_c,              \
    48              got, data[i].want, data[i].size);   \
    49    } while (0)
    50  
    51  typedef mp_limb_t (*mpn_aors_1_t) (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
    52  mpn_aors_1_t fudge (mpn_aors_1_t);
    53  
    54  
    55  void
    56  verify (const char *name, int i,
    57          mp_srcptr src, mp_limb_t n,
    58          mp_limb_t got_c, mp_limb_t want_c,
    59          mp_srcptr got, mp_srcptr want, mp_size_t size)
    60  {
    61    if (got[size] != MAGIC)
    62      {
    63        printf ("Overwrite at %s i=%d\n", name, i);
    64        abort ();
    65      }
    66  
    67    if (got_c != want_c || ! refmpn_equal_anynail (got, want, size))
    68      {
    69        printf ("Wrong at %s i=%d size=%ld\n", name, i, size);
    70        mpn_trace ("   src", src,  size);
    71        mpn_trace ("     n", &n,   (mp_size_t) 1);
    72        mpn_trace ("   got", got,  size);
    73        mpn_trace ("  want", want, size);
    74        mpn_trace (" got c", &got_c,  (mp_size_t) 1);
    75        mpn_trace ("want c", &want_c, (mp_size_t) 1);
    76        abort ();
    77      }
    78  }
    79  
    80  
    81  void
    82  check_add_1 (void)
    83  {
    84    static const struct {
    85      mp_size_t        size;
    86      mp_limb_t        n;
    87      const mp_limb_t  src[ASIZE];
    88      mp_limb_t        want_c;
    89      const mp_limb_t  want[ASIZE];
    90    } data[] = {
    91      { 1, 0, { 0 },  0, { 0 } },
    92      { 1, 0, { 1 },  0, { 1 } },
    93      { 1, 1, { 0 },  0, { 1 } },
    94      { 1, 0, { M },  0, { M } },
    95      { 1, M, { 0 },  0, { M } },
    96      { 1, 1, { 123 }, 0, { 124 } },
    97  
    98      { 1, 1, { M },  1, { 0 } },
    99      { 1, M, { 1 },  1, { 0 } },
   100      { 1, M, { M },  1, { M-1 } },
   101  
   102      { 2, 0, { 0, 0 },  0, { 0, 0 } },
   103      { 2, 0, { 1, 0 },  0, { 1, 0 } },
   104      { 2, 1, { 0, 0 },  0, { 1, 0 } },
   105      { 2, 0, { M, 0 },  0, { M, 0 } },
   106      { 2, M, { 0, 0 },  0, { M, 0 } },
   107      { 2, 1, { M, 0 },  0, { 0, 1 } },
   108      { 2, M, { 1, 0 },  0, { 0, 1 } },
   109      { 2, M, { M, 0 },  0, { M-1, 1 } },
   110      { 2, M, { M, 0 },  0, { M-1, 1 } },
   111  
   112      { 2, 1, { M, M },  1, { 0, 0 } },
   113      { 2, M, { 1, M },  1, { 0, 0 } },
   114      { 2, M, { M, M },  1, { M-1, 0 } },
   115      { 2, M, { M, M },  1, { M-1, 0 } },
   116  
   117      { 3, 1, { M, M, M },  1, { 0, 0, 0 } },
   118      { 3, M, { 1, M, M },  1, { 0, 0, 0 } },
   119      { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
   120      { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
   121  
   122      { 4, 1, { M, M, M, M },  1, { 0, 0, 0, 0 } },
   123      { 4, M, { 1, M, M, M },  1, { 0, 0, 0, 0 } },
   124      { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
   125      { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
   126  
   127      { 4, M, { M, 0,   M, M },  0, { M-1, 1, M, M } },
   128      { 4, M, { M, M-1, M, M },  0, { M-1, M, M, M } },
   129  
   130      { 4, M, { M, M, 0,   M },  0, { M-1, 0, 1, M } },
   131      { 4, M, { M, M, M-1, M },  0, { M-1, 0, M, M } },
   132    };
   133  
   134    mp_limb_t  got[ASIZE];
   135    mp_limb_t  got_c;
   136    /* mpn_sec_add_a_itch(n) <= n */
   137    mp_limb_t  scratch[ASIZE];
   138    int        i;
   139  
   140    for (i = 0; i < numberof (data); i++)
   141      {
   142        SETUP ();
   143        got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n);
   144        VERIFY ("check_add_1 (separate)");
   145  
   146        SETUP_INPLACE ();
   147        got_c = mpn_add_1 (got, got, data[i].size, data[i].n);
   148        VERIFY ("check_add_1 (in-place)");
   149  
   150        SETUP ();
   151        scratch [mpn_sec_add_1_itch(data[i].size)] = MAGIC;
   152        got_c = mpn_sec_add_1 (got, data[i].src, data[i].size, data[i].n, scratch);
   153        got_c ^= scratch [mpn_sec_add_1_itch(data[i].size)] ^ MAGIC;
   154        VERIFY ("check_sec_add_1 (separate)");
   155  
   156        SETUP_INPLACE ();
   157        got_c = mpn_sec_add_1 (got, got, data[i].size, data[i].n, scratch);
   158        VERIFY ("check_sec_add_1 (in-place)");
   159  
   160        if (data[i].n == 1)
   161          {
   162            SETUP ();
   163            got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
   164            VERIFY ("check_add_1 (separate, const 1)");
   165  
   166            SETUP_INPLACE ();
   167            got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1));
   168            VERIFY ("check_add_1 (in-place, const 1)");
   169  
   170            SETUP ();
   171            got_c = mpn_sec_add_1 (got, data[i].src, data[i].size,
   172  				 CNST_LIMB(1), scratch);
   173            VERIFY ("check_sec_add_1 (separate, const 1)");
   174  
   175            SETUP_INPLACE ();
   176            got_c = mpn_sec_add_1 (got, got, data[i].size,
   177  				 CNST_LIMB(1), scratch);
   178            VERIFY ("check_sec_add_1 (in-place, const 1)");
   179          }
   180  
   181        /* Same again on functions, not inlines. */
   182        SETUP ();
   183        got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n);
   184        VERIFY ("check_add_1 (function, separate)");
   185  
   186        SETUP_INPLACE ();
   187        got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n);
   188        VERIFY ("check_add_1 (function, in-place)");
   189      }
   190  }
   191  
   192  void
   193  check_sub_1 (void)
   194  {
   195    static const struct {
   196      mp_size_t        size;
   197      mp_limb_t        n;
   198      const mp_limb_t  src[ASIZE];
   199      mp_limb_t        want_c;
   200      const mp_limb_t  want[ASIZE];
   201    } data[] = {
   202      { 1, 0, { 0 },  0, { 0 } },
   203      { 1, 0, { 1 },  0, { 1 } },
   204      { 1, 1, { 1 },  0, { 0 } },
   205      { 1, 0, { M },  0, { M } },
   206      { 1, 1, { M },  0, { M-1 } },
   207      { 1, 1, { 123 }, 0, { 122 } },
   208  
   209      { 1, 1, { 0 },  1, { M } },
   210      { 1, M, { 0 },  1, { 1 } },
   211  
   212      { 2, 0, { 0, 0 },  0, { 0, 0 } },
   213      { 2, 0, { 1, 0 },  0, { 1, 0 } },
   214      { 2, 1, { 1, 0 },  0, { 0, 0 } },
   215      { 2, 0, { M, 0 },  0, { M, 0 } },
   216      { 2, 1, { M, 0 },  0, { M-1, 0 } },
   217      { 2, 1, { 123, 0 }, 0, { 122, 0 } },
   218  
   219      { 2, 1, { 0, 0 },  1, { M, M } },
   220      { 2, M, { 0, 0 },  1, { 1, M } },
   221  
   222      { 3, 0, { 0,   0, 0 },  0, { 0,   0, 0 } },
   223      { 3, 0, { 123, 0, 0 },  0, { 123, 0, 0 } },
   224  
   225      { 3, 1, { 0, 0, 0 },  1, { M, M, M } },
   226      { 3, M, { 0, 0, 0 },  1, { 1, M, M } },
   227  
   228      { 4, 1, { 0, 0, 0, 0 },  1, { M, M, M, M } },
   229      { 4, M, { 0, 0, 0, 0 },  1, { 1, M, M, M } },
   230  
   231      { 4, 1, { 0, 0, 1,   42 },  0, { M, M, 0,   42 } },
   232      { 4, M, { 0, 0, 123, 24 },  0, { 1, M, 122, 24 } },
   233    };
   234  
   235    mp_limb_t  got[ASIZE];
   236    mp_limb_t  got_c;
   237    /* mpn_sec_sub_1_itch(n) <= n */
   238    mp_limb_t  scratch[ASIZE];
   239    int        i;
   240  
   241    for (i = 0; i < numberof (data); i++)
   242      {
   243        SETUP ();
   244        got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n);
   245        VERIFY ("check_sub_1 (separate)");
   246  
   247        SETUP_INPLACE ();
   248        got_c = mpn_sub_1 (got, got, data[i].size, data[i].n);
   249        VERIFY ("check_sub_1 (in-place)");
   250  
   251        SETUP ();
   252        scratch [mpn_sec_sub_1_itch(data[i].size)] = MAGIC;
   253        got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size, data[i].n, scratch);
   254        got_c ^= scratch [mpn_sec_sub_1_itch(data[i].size)] ^ MAGIC;
   255        VERIFY ("check_sec_sub_1 (separate)");
   256  
   257        SETUP_INPLACE ();
   258        got_c = mpn_sec_sub_1 (got, got, data[i].size, data[i].n, scratch);
   259        VERIFY ("check_sec_sub_1 (in-place)");
   260  
   261        if (data[i].n == 1)
   262          {
   263            SETUP ();
   264            got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
   265            VERIFY ("check_sub_1 (separate, const 1)");
   266  
   267            SETUP_INPLACE ();
   268            got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1));
   269            VERIFY ("check_sub_1 (in-place, const 1)");
   270  
   271            SETUP ();
   272            got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size,
   273  				 CNST_LIMB(1), scratch);
   274            VERIFY ("check_sec_sub_1 (separate, const 1)");
   275  
   276            SETUP_INPLACE ();
   277            got_c = mpn_sec_sub_1 (got, got, data[i].size,
   278  				 CNST_LIMB(1), scratch);
   279            VERIFY ("check_sec_sub_1 (in-place, const 1)");
   280          }
   281  
   282        /* Same again on functions, not inlines. */
   283        SETUP ();
   284        got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n);
   285        VERIFY ("check_sub_1 (function, separate)");
   286  
   287        SETUP_INPLACE ();
   288        got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n);
   289        VERIFY ("check_sub_1 (function, in-place)");
   290      }
   291  }
   292  
   293  /* Try to prevent the optimizer inlining. */
   294  mpn_aors_1_t
   295  fudge (mpn_aors_1_t f)
   296  {
   297    return f;
   298  }
   299  
   300  int
   301  main (void)
   302  {
   303    tests_start ();
   304    mp_trace_base = -16;
   305  
   306    check_add_1 ();
   307    check_sub_1 ();
   308  
   309    tests_end ();
   310    exit (0);
   311  }