Home | History | Annotate | Line # | Download | only in mpn
t-aors_1.c revision 1.1.1.3
      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 }
    312