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