t-aors_1.c revision 1.1.1.2 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 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) (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 int i;
137
138 for (i = 0; i < numberof (data); i++)
139 {
140 SETUP ();
141 got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n);
142 VERIFY ("check_add_1 (separate)");
143
144 SETUP_INPLACE ();
145 got_c = mpn_add_1 (got, got, data[i].size, data[i].n);
146 VERIFY ("check_add_1 (in-place)");
147
148 if (data[i].n == 1)
149 {
150 SETUP ();
151 got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
152 VERIFY ("check_add_1 (separate, const 1)");
153
154 SETUP_INPLACE ();
155 got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1));
156 VERIFY ("check_add_1 (in-place, const 1)");
157 }
158
159 /* Same again on functions, not inlines. */
160 SETUP ();
161 got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n);
162 VERIFY ("check_add_1 (function, separate)");
163
164 SETUP_INPLACE ();
165 got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n);
166 VERIFY ("check_add_1 (function, in-place)");
167 }
168 }
169
170 void
171 check_sub_1 (void)
172 {
173 static const struct {
174 mp_size_t size;
175 mp_limb_t n;
176 const mp_limb_t src[ASIZE];
177 mp_limb_t want_c;
178 const mp_limb_t want[ASIZE];
179 } data[] = {
180 { 1, 0, { 0 }, 0, { 0 } },
181 { 1, 0, { 1 }, 0, { 1 } },
182 { 1, 1, { 1 }, 0, { 0 } },
183 { 1, 0, { M }, 0, { M } },
184 { 1, 1, { M }, 0, { M-1 } },
185 { 1, 1, { 123 }, 0, { 122 } },
186
187 { 1, 1, { 0 }, 1, { M } },
188 { 1, M, { 0 }, 1, { 1 } },
189
190 { 2, 0, { 0, 0 }, 0, { 0, 0 } },
191 { 2, 0, { 1, 0 }, 0, { 1, 0 } },
192 { 2, 1, { 1, 0 }, 0, { 0, 0 } },
193 { 2, 0, { M, 0 }, 0, { M, 0 } },
194 { 2, 1, { M, 0 }, 0, { M-1, 0 } },
195 { 2, 1, { 123, 0 }, 0, { 122, 0 } },
196
197 { 2, 1, { 0, 0 }, 1, { M, M } },
198 { 2, M, { 0, 0 }, 1, { 1, M } },
199
200 { 3, 0, { 0, 0, 0 }, 0, { 0, 0, 0 } },
201 { 3, 0, { 123, 0, 0 }, 0, { 123, 0, 0 } },
202
203 { 3, 1, { 0, 0, 0 }, 1, { M, M, M } },
204 { 3, M, { 0, 0, 0 }, 1, { 1, M, M } },
205
206 { 4, 1, { 0, 0, 0, 0 }, 1, { M, M, M, M } },
207 { 4, M, { 0, 0, 0, 0 }, 1, { 1, M, M, M } },
208
209 { 4, 1, { 0, 0, 1, 42 }, 0, { M, M, 0, 42 } },
210 { 4, M, { 0, 0, 123, 24 }, 0, { 1, M, 122, 24 } },
211 };
212
213 mp_limb_t got[ASIZE];
214 mp_limb_t got_c;
215 int i;
216
217 for (i = 0; i < numberof (data); i++)
218 {
219 SETUP ();
220 got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n);
221 VERIFY ("check_sub_1 (separate)");
222
223 SETUP_INPLACE ();
224 got_c = mpn_sub_1 (got, got, data[i].size, data[i].n);
225 VERIFY ("check_sub_1 (in-place)");
226
227 if (data[i].n == 1)
228 {
229 SETUP ();
230 got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
231 VERIFY ("check_sub_1 (separate, const 1)");
232
233 SETUP_INPLACE ();
234 got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1));
235 VERIFY ("check_sub_1 (in-place, const 1)");
236 }
237
238 /* Same again on functions, not inlines. */
239 SETUP ();
240 got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n);
241 VERIFY ("check_sub_1 (function, separate)");
242
243 SETUP_INPLACE ();
244 got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n);
245 VERIFY ("check_sub_1 (function, in-place)");
246 }
247 }
248
249 /* Try to prevent the optimizer inlining. */
250 mpn_aors_1_t
251 fudge (mpn_aors_1_t f)
252 {
253 return f;
254 }
255
256 int
257 main (void)
258 {
259 tests_start ();
260 mp_trace_base = -16;
261
262 check_add_1 ();
263 check_sub_1 ();
264
265 tests_end ();
266 exit (0);
267 }
268