xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpn/t-aors_1.c (revision b757af438b42b93f8c6571f026d8b8ef3eaf5fc9)
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