Home | History | Annotate | Line # | Download | only in mpn
t-aors_1.c revision 1.1
      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.
      6 
      7 The GNU MP Library is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU Lesser General Public License as published by
      9 the Free Software Foundation; either version 3 of the License, or (at your
     10 option) any later version.
     11 
     12 The GNU MP Library is distributed in the hope that it will be useful, but
     13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     15 License for more details.
     16 
     17 You should have received a copy of the GNU Lesser General Public License
     18 along with the GNU MP Library.  If not, see http://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)
     52      __GMP_PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
     53 mpn_aors_1_t fudge __GMP_PROTO ((mpn_aors_1_t));
     54 
     55 
     56 void
     57 verify (const char *name, int i,
     58         mp_srcptr src, mp_limb_t n,
     59         mp_limb_t got_c, mp_limb_t want_c,
     60         mp_srcptr got, mp_srcptr want, mp_size_t size)
     61 {
     62   if (got[size] != MAGIC)
     63     {
     64       printf ("Overwrite at %s i=%d\n", name, i);
     65       abort ();
     66     }
     67 
     68   if (got_c != want_c || ! refmpn_equal_anynail (got, want, size))
     69     {
     70       printf ("Wrong at %s i=%d size=%ld\n", name, i, size);
     71       mpn_trace ("   src", src,  size);
     72       mpn_trace ("     n", &n,   (mp_size_t) 1);
     73       mpn_trace ("   got", got,  size);
     74       mpn_trace ("  want", want, size);
     75       mpn_trace (" got c", &got_c,  (mp_size_t) 1);
     76       mpn_trace ("want c", &want_c, (mp_size_t) 1);
     77       abort ();
     78     }
     79 }
     80 
     81 
     82 void
     83 check_add_1 (void)
     84 {
     85   static const struct {
     86     mp_size_t        size;
     87     mp_limb_t        n;
     88     const mp_limb_t  src[ASIZE];
     89     mp_limb_t        want_c;
     90     const mp_limb_t  want[ASIZE];
     91   } data[] = {
     92     { 1, 0, { 0 },  0, { 0 } },
     93     { 1, 0, { 1 },  0, { 1 } },
     94     { 1, 1, { 0 },  0, { 1 } },
     95     { 1, 0, { M },  0, { M } },
     96     { 1, M, { 0 },  0, { M } },
     97     { 1, 1, { 123 }, 0, { 124 } },
     98 
     99     { 1, 1, { M },  1, { 0 } },
    100     { 1, M, { 1 },  1, { 0 } },
    101     { 1, M, { M },  1, { M-1 } },
    102 
    103     { 2, 0, { 0, 0 },  0, { 0, 0 } },
    104     { 2, 0, { 1, 0 },  0, { 1, 0 } },
    105     { 2, 1, { 0, 0 },  0, { 1, 0 } },
    106     { 2, 0, { M, 0 },  0, { M, 0 } },
    107     { 2, M, { 0, 0 },  0, { M, 0 } },
    108     { 2, 1, { M, 0 },  0, { 0, 1 } },
    109     { 2, M, { 1, 0 },  0, { 0, 1 } },
    110     { 2, M, { M, 0 },  0, { M-1, 1 } },
    111     { 2, M, { M, 0 },  0, { M-1, 1 } },
    112 
    113     { 2, 1, { M, M },  1, { 0, 0 } },
    114     { 2, M, { 1, M },  1, { 0, 0 } },
    115     { 2, M, { M, M },  1, { M-1, 0 } },
    116     { 2, M, { M, M },  1, { M-1, 0 } },
    117 
    118     { 3, 1, { M, M, M },  1, { 0, 0, 0 } },
    119     { 3, M, { 1, M, M },  1, { 0, 0, 0 } },
    120     { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
    121     { 3, M, { M, M, M },  1, { M-1, 0, 0 } },
    122 
    123     { 4, 1, { M, M, M, M },  1, { 0, 0, 0, 0 } },
    124     { 4, M, { 1, M, M, M },  1, { 0, 0, 0, 0 } },
    125     { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
    126     { 4, M, { M, M, M, M },  1, { M-1, 0, 0, 0 } },
    127 
    128     { 4, M, { M, 0,   M, M },  0, { M-1, 1, M, M } },
    129     { 4, M, { M, M-1, M, M },  0, { M-1, M, M, M } },
    130 
    131     { 4, M, { M, M, 0,   M },  0, { M-1, 0, 1, M } },
    132     { 4, M, { M, M, M-1, M },  0, { M-1, 0, M, M } },
    133   };
    134 
    135   mp_limb_t  got[ASIZE];
    136   mp_limb_t  got_c;
    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       if (data[i].n == 1)
    150         {
    151           SETUP ();
    152           got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
    153           VERIFY ("check_add_1 (separate, const 1)");
    154 
    155           SETUP_INPLACE ();
    156           got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1));
    157           VERIFY ("check_add_1 (in-place, const 1)");
    158         }
    159 
    160       /* Same again on functions, not inlines. */
    161       SETUP ();
    162       got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n);
    163       VERIFY ("check_add_1 (function, separate)");
    164 
    165       SETUP_INPLACE ();
    166       got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n);
    167       VERIFY ("check_add_1 (function, in-place)");
    168     }
    169 }
    170 
    171 void
    172 check_sub_1 (void)
    173 {
    174   static const struct {
    175     mp_size_t        size;
    176     mp_limb_t        n;
    177     const mp_limb_t  src[ASIZE];
    178     mp_limb_t        want_c;
    179     const mp_limb_t  want[ASIZE];
    180   } data[] = {
    181     { 1, 0, { 0 },  0, { 0 } },
    182     { 1, 0, { 1 },  0, { 1 } },
    183     { 1, 1, { 1 },  0, { 0 } },
    184     { 1, 0, { M },  0, { M } },
    185     { 1, 1, { M },  0, { M-1 } },
    186     { 1, 1, { 123 }, 0, { 122 } },
    187 
    188     { 1, 1, { 0 },  1, { M } },
    189     { 1, M, { 0 },  1, { 1 } },
    190 
    191     { 2, 0, { 0, 0 },  0, { 0, 0 } },
    192     { 2, 0, { 1, 0 },  0, { 1, 0 } },
    193     { 2, 1, { 1, 0 },  0, { 0, 0 } },
    194     { 2, 0, { M, 0 },  0, { M, 0 } },
    195     { 2, 1, { M, 0 },  0, { M-1, 0 } },
    196     { 2, 1, { 123, 0 }, 0, { 122, 0 } },
    197 
    198     { 2, 1, { 0, 0 },  1, { M, M } },
    199     { 2, M, { 0, 0 },  1, { 1, M } },
    200 
    201     { 3, 0, { 0,   0, 0 },  0, { 0,   0, 0 } },
    202     { 3, 0, { 123, 0, 0 },  0, { 123, 0, 0 } },
    203 
    204     { 3, 1, { 0, 0, 0 },  1, { M, M, M } },
    205     { 3, M, { 0, 0, 0 },  1, { 1, M, M } },
    206 
    207     { 4, 1, { 0, 0, 0, 0 },  1, { M, M, M, M } },
    208     { 4, M, { 0, 0, 0, 0 },  1, { 1, M, M, M } },
    209 
    210     { 4, 1, { 0, 0, 1,   42 },  0, { M, M, 0,   42 } },
    211     { 4, M, { 0, 0, 123, 24 },  0, { 1, M, 122, 24 } },
    212   };
    213 
    214   mp_limb_t  got[ASIZE];
    215   mp_limb_t  got_c;
    216   int        i;
    217 
    218   for (i = 0; i < numberof (data); i++)
    219     {
    220       SETUP ();
    221       got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n);
    222       VERIFY ("check_sub_1 (separate)");
    223 
    224       SETUP_INPLACE ();
    225       got_c = mpn_sub_1 (got, got, data[i].size, data[i].n);
    226       VERIFY ("check_sub_1 (in-place)");
    227 
    228       if (data[i].n == 1)
    229         {
    230           SETUP ();
    231           got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
    232           VERIFY ("check_sub_1 (separate, const 1)");
    233 
    234           SETUP_INPLACE ();
    235           got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1));
    236           VERIFY ("check_sub_1 (in-place, const 1)");
    237         }
    238 
    239       /* Same again on functions, not inlines. */
    240       SETUP ();
    241       got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n);
    242       VERIFY ("check_sub_1 (function, separate)");
    243 
    244       SETUP_INPLACE ();
    245       got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n);
    246       VERIFY ("check_sub_1 (function, in-place)");
    247     }
    248 }
    249 
    250 /* Try to prevent the optimizer inlining. */
    251 mpn_aors_1_t
    252 fudge (mpn_aors_1_t f)
    253 {
    254   return f;
    255 }
    256 
    257 int
    258 main (void)
    259 {
    260   tests_start ();
    261   mp_trace_base = -16;
    262 
    263   check_add_1 ();
    264   check_sub_1 ();
    265 
    266   tests_end ();
    267   exit (0);
    268 }
    269