(root)/
gmp-6.3.0/
tests/
mpn/
t-aors_1.c
       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-impl.h"
      24  #include "tests.h"
      25  
      26  
      27  #define M      GMP_NUMB_MAX
      28  #define ASIZE  10
      29  #define MAGIC  0x1234
      30  
      31  #define SETUP()                         \
      32    do {                                  \
      33      refmpn_random (got, data[i].size);  \
      34      got[data[i].size] = MAGIC;          \
      35    } while (0)
      36  
      37  #define SETUP_INPLACE()                                 \
      38    do {                                                  \
      39      refmpn_copyi (got, data[i].src, data[i].size);      \
      40      got[data[i].size] = MAGIC;                          \
      41    } while (0)
      42  
      43  #define VERIFY(name)                            \
      44    do {                                          \
      45      verify (name, i, data[i].src, data[i].n,    \
      46              got_c, data[i].want_c,              \
      47              got, data[i].want, data[i].size);   \
      48    } while (0)
      49  
      50  typedef mp_limb_t (*mpn_aors_1_t) (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
      51  mpn_aors_1_t fudge (mpn_aors_1_t);
      52  
      53  
      54  void
      55  verify (const char *name, int i,
      56          mp_srcptr src, mp_limb_t n,
      57          mp_limb_t got_c, mp_limb_t want_c,
      58          mp_srcptr got, mp_srcptr want, mp_size_t size)
      59  {
      60    if (got[size] != MAGIC)
      61      {
      62        printf ("Overwrite at %s i=%d\n", name, i);
      63        abort ();
      64      }
      65  
      66    if (got_c != want_c || ! refmpn_equal_anynail (got, want, size))
      67      {
      68        printf ("Wrong at %s i=%d size=%ld\n", name, i, size);
      69        mpn_trace ("   src", src,  size);
      70        mpn_trace ("     n", &n,   (mp_size_t) 1);
      71        mpn_trace ("   got", got,  size);
      72        mpn_trace ("  want", want, size);
      73        mpn_trace (" got c", &got_c,  (mp_size_t) 1);
      74        mpn_trace ("want c", &want_c, (mp_size_t) 1);
      75        abort ();
      76      }
      77  }
      78  
      79  
      80  void
      81  check_add_1 (void)
      82  {
      83    static const struct {
      84      mp_size_t        size;
      85      mp_limb_t        n;
      86      const mp_limb_t  src[ASIZE];
      87      mp_limb_t        want_c;
      88      const mp_limb_t  want[ASIZE];
      89    } data[] = {
      90      { 1, 0, { 0 },  0, { 0 } },
      91      { 1, 0, { 1 },  0, { 1 } },
      92      { 1, 1, { 0 },  0, { 1 } },
      93      { 1, 0, { M },  0, { M } },
      94      { 1, M, { 0 },  0, { M } },
      95      { 1, 1, { 123 }, 0, { 124 } },
      96  
      97      { 1, 1, { M },  1, { 0 } },
      98      { 1, M, { 1 },  1, { 0 } },
      99      { 1, M, { M },  1, { M-1 } },
     100  
     101      { 2, 0, { 0, 0 },  0, { 0, 0 } },
     102      { 2, 0, { 1, 0 },  0, { 1, 0 } },
     103      { 2, 1, { 0, 0 },  0, { 1, 0 } },
     104      { 2, 0, { M, 0 },  0, { M, 0 } },
     105      { 2, M, { 0, 0 },  0, { M, 0 } },
     106      { 2, 1, { M, 0 },  0, { 0, 1 } },
     107      { 2, M, { 1, 0 },  0, { 0, 1 } },
     108      { 2, M, { M, 0 },  0, { M-1, 1 } },
     109      { 2, M, { M, 0 },  0, { M-1, 1 } },
     110  
     111      { 2, 1, { M, M },  1, { 0, 0 } },
     112      { 2, M, { 1, M },  1, { 0, 0 } },
     113      { 2, M, { M, M },  1, { M-1, 0 } },
     114      { 2, M, { M, M },  1, { M-1, 0 } },
     115  
     116      { 3, 1, { M, M, M },  1, { 0, 0, 0 } },
     117      { 3, M, { 1, M, M },  1, { 0, 0, 0 } },
     118      { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
     119      { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
     120  
     121      { 4, 1, { M, M, M, M },  1, { 0, 0, 0, 0 } },
     122      { 4, M, { 1, M, M, M },  1, { 0, 0, 0, 0 } },
     123      { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
     124      { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
     125  
     126      { 4, M, { M, 0,   M, M },  0, { M-1, 1, M, M } },
     127      { 4, M, { M, M-1, M, M },  0, { M-1, M, M, M } },
     128  
     129      { 4, M, { M, M, 0,   M },  0, { M-1, 0, 1, M } },
     130      { 4, M, { M, M, M-1, M },  0, { M-1, 0, M, M } },
     131    };
     132  
     133    mp_limb_t  got[ASIZE];
     134    mp_limb_t  got_c;
     135    /* mpn_sec_add_a_itch(n) <= n */
     136    mp_limb_t  scratch[ASIZE];
     137    int        i;
     138  
     139    for (i = 0; i < numberof (data); i++)
     140      {
     141        SETUP ();
     142        got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n);
     143        VERIFY ("check_add_1 (separate)");
     144  
     145        SETUP_INPLACE ();
     146        got_c = mpn_add_1 (got, got, data[i].size, data[i].n);
     147        VERIFY ("check_add_1 (in-place)");
     148  
     149        SETUP ();
     150        scratch [mpn_sec_add_1_itch(data[i].size)] = MAGIC;
     151        got_c = mpn_sec_add_1 (got, data[i].src, data[i].size, data[i].n, scratch);
     152        got_c ^= scratch [mpn_sec_add_1_itch(data[i].size)] ^ MAGIC;
     153        VERIFY ("check_sec_add_1 (separate)");
     154  
     155        SETUP_INPLACE ();
     156        got_c = mpn_sec_add_1 (got, got, data[i].size, data[i].n, scratch);
     157        VERIFY ("check_sec_add_1 (in-place)");
     158  
     159        if (data[i].n == 1)
     160          {
     161            SETUP ();
     162            got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
     163            VERIFY ("check_add_1 (separate, const 1)");
     164  
     165            SETUP_INPLACE ();
     166            got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1));
     167            VERIFY ("check_add_1 (in-place, const 1)");
     168  
     169            SETUP ();
     170            got_c = mpn_sec_add_1 (got, data[i].src, data[i].size,
     171  				 CNST_LIMB(1), scratch);
     172            VERIFY ("check_sec_add_1 (separate, const 1)");
     173  
     174            SETUP_INPLACE ();
     175            got_c = mpn_sec_add_1 (got, got, data[i].size,
     176  				 CNST_LIMB(1), scratch);
     177            VERIFY ("check_sec_add_1 (in-place, const 1)");
     178          }
     179  
     180        /* Same again on functions, not inlines. */
     181        SETUP ();
     182        got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n);
     183        VERIFY ("check_add_1 (function, separate)");
     184  
     185        SETUP_INPLACE ();
     186        got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n);
     187        VERIFY ("check_add_1 (function, in-place)");
     188      }
     189  }
     190  
     191  void
     192  check_sub_1 (void)
     193  {
     194    static const struct {
     195      mp_size_t        size;
     196      mp_limb_t        n;
     197      const mp_limb_t  src[ASIZE];
     198      mp_limb_t        want_c;
     199      const mp_limb_t  want[ASIZE];
     200    } data[] = {
     201      { 1, 0, { 0 },  0, { 0 } },
     202      { 1, 0, { 1 },  0, { 1 } },
     203      { 1, 1, { 1 },  0, { 0 } },
     204      { 1, 0, { M },  0, { M } },
     205      { 1, 1, { M },  0, { M-1 } },
     206      { 1, 1, { 123 }, 0, { 122 } },
     207  
     208      { 1, 1, { 0 },  1, { M } },
     209      { 1, M, { 0 },  1, { 1 } },
     210  
     211      { 2, 0, { 0, 0 },  0, { 0, 0 } },
     212      { 2, 0, { 1, 0 },  0, { 1, 0 } },
     213      { 2, 1, { 1, 0 },  0, { 0, 0 } },
     214      { 2, 0, { M, 0 },  0, { M, 0 } },
     215      { 2, 1, { M, 0 },  0, { M-1, 0 } },
     216      { 2, 1, { 123, 0 }, 0, { 122, 0 } },
     217  
     218      { 2, 1, { 0, 0 },  1, { M, M } },
     219      { 2, M, { 0, 0 },  1, { 1, M } },
     220  
     221      { 3, 0, { 0,   0, 0 },  0, { 0,   0, 0 } },
     222      { 3, 0, { 123, 0, 0 },  0, { 123, 0, 0 } },
     223  
     224      { 3, 1, { 0, 0, 0 },  1, { M, M, M } },
     225      { 3, M, { 0, 0, 0 },  1, { 1, M, M } },
     226  
     227      { 4, 1, { 0, 0, 0, 0 },  1, { M, M, M, M } },
     228      { 4, M, { 0, 0, 0, 0 },  1, { 1, M, M, M } },
     229  
     230      { 4, 1, { 0, 0, 1,   42 },  0, { M, M, 0,   42 } },
     231      { 4, M, { 0, 0, 123, 24 },  0, { 1, M, 122, 24 } },
     232    };
     233  
     234    mp_limb_t  got[ASIZE];
     235    mp_limb_t  got_c;
     236    /* mpn_sec_sub_1_itch(n) <= n */
     237    mp_limb_t  scratch[ASIZE];
     238    int        i;
     239  
     240    for (i = 0; i < numberof (data); i++)
     241      {
     242        SETUP ();
     243        got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n);
     244        VERIFY ("check_sub_1 (separate)");
     245  
     246        SETUP_INPLACE ();
     247        got_c = mpn_sub_1 (got, got, data[i].size, data[i].n);
     248        VERIFY ("check_sub_1 (in-place)");
     249  
     250        SETUP ();
     251        scratch [mpn_sec_sub_1_itch(data[i].size)] = MAGIC;
     252        got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size, data[i].n, scratch);
     253        got_c ^= scratch [mpn_sec_sub_1_itch(data[i].size)] ^ MAGIC;
     254        VERIFY ("check_sec_sub_1 (separate)");
     255  
     256        SETUP_INPLACE ();
     257        got_c = mpn_sec_sub_1 (got, got, data[i].size, data[i].n, scratch);
     258        VERIFY ("check_sec_sub_1 (in-place)");
     259  
     260        if (data[i].n == 1)
     261          {
     262            SETUP ();
     263            got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
     264            VERIFY ("check_sub_1 (separate, const 1)");
     265  
     266            SETUP_INPLACE ();
     267            got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1));
     268            VERIFY ("check_sub_1 (in-place, const 1)");
     269  
     270            SETUP ();
     271            got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size,
     272  				 CNST_LIMB(1), scratch);
     273            VERIFY ("check_sec_sub_1 (separate, const 1)");
     274  
     275            SETUP_INPLACE ();
     276            got_c = mpn_sec_sub_1 (got, got, data[i].size,
     277  				 CNST_LIMB(1), scratch);
     278            VERIFY ("check_sec_sub_1 (in-place, const 1)");
     279          }
     280  
     281        /* Same again on functions, not inlines. */
     282        SETUP ();
     283        got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n);
     284        VERIFY ("check_sub_1 (function, separate)");
     285  
     286        SETUP_INPLACE ();
     287        got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n);
     288        VERIFY ("check_sub_1 (function, in-place)");
     289      }
     290  }
     291  
     292  /* Try to prevent the optimizer inlining. */
     293  mpn_aors_1_t
     294  fudge (mpn_aors_1_t f)
     295  {
     296    return f;
     297  }
     298  
     299  int
     300  main (void)
     301  {
     302    tests_start ();
     303    mp_trace_base = -16;
     304  
     305    check_add_1 ();
     306    check_sub_1 ();
     307  
     308    tests_end ();
     309    exit (0);
     310  }