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