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