f10c7e9a |
1 | /* -*-c-*- |
2 | * |
3 | * $Id: mpx-test.c,v 1.1 1999/11/13 01:50:04 mdw Exp $ |
4 | */ |
5 | |
6 | #include <stdio.h> |
7 | #include <stdlib.h> |
8 | #include <string.h> |
9 | |
10 | #include <mLib/alloc.h> |
11 | #include <mLib/dstr.h> |
12 | #include <mLib/quis.h> |
13 | #include <mLib/testrig.h> |
14 | |
15 | #include "mpx.h" |
16 | #include "mpscan.h" |
17 | |
18 | #define ALLOC(v, vl, sz) do { \ |
19 | size_t _sz = (sz); \ |
20 | mpw *_vv = xmalloc(MPWS(_sz)); \ |
21 | mpw *_vvl = _vv + _sz; \ |
22 | (v) = _vv; \ |
23 | (vl) = _vvl; \ |
24 | } while (0) |
25 | |
26 | #define LOAD(v, vl, d) do { \ |
27 | const dstr *_d = (d); \ |
28 | mpw *_v, *_vl; \ |
29 | ALLOC(_v, _vl, MPW_RQ(_d->len)); \ |
30 | mpx_loadb(_v, _vl, _d->buf, _d->len); \ |
31 | (v) = _v; \ |
32 | (vl) = _vl; \ |
33 | } while (0) |
34 | |
35 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) |
36 | |
37 | static void dumpbits(const char *msg, const void *pp, size_t sz) |
38 | { |
39 | const octet *p = pp; |
40 | fputs(msg, stderr); |
41 | for (; sz; sz--) |
42 | fprintf(stderr, " %02x", *p++); |
43 | fputc('\n', stderr); |
44 | } |
45 | |
46 | static void dumpmp(const char *msg, const mpw *v, const mpw *vl) |
47 | { |
48 | fputs(msg, stderr); |
49 | MPX_SHRINK(v, vl); |
50 | while (v < vl) |
51 | fprintf(stderr, " %08lx", (unsigned long)*--vl); |
52 | fputc('\n', stderr); |
53 | } |
54 | |
55 | static int chkscan(const mpw *v, const mpw *vl, |
56 | const void *pp, size_t sz, int step) |
57 | { |
58 | mpscan mps; |
59 | const octet *p = pp; |
60 | unsigned bit = 0; |
61 | int ok = 1; |
62 | |
63 | mpscan_initx(&mps, v, vl); |
64 | while (sz) { |
65 | unsigned x = *p; |
66 | int i; |
67 | p += step; |
68 | for (i = 0; i < 8 && MPSCAN_STEP(&mps); i++) { |
69 | if (MPSCAN_BIT(&mps) != (x & 1)) { |
70 | fprintf(stderr, |
71 | "\n*** error, step %i, bit %u, expected %u, found %u\n", |
72 | step, bit, x & 1, MPSCAN_BIT(&mps)); |
73 | ok = 0; |
74 | } |
75 | x >>= 1; |
76 | bit++; |
77 | } |
78 | sz--; |
79 | } |
80 | |
81 | return (ok); |
82 | } |
83 | |
84 | static int loadstore(dstr *v) |
85 | { |
86 | dstr d = DSTR_INIT; |
87 | size_t sz = MPW_RQ(v->len) * 2, diff; |
88 | mpw *m, *ml; |
89 | int ok = 1; |
90 | |
91 | dstr_ensure(&d, v->len); |
92 | m = xmalloc(MPWS(sz)); |
93 | |
94 | for (diff = 0; diff < sz; diff += 5) { |
95 | size_t oct; |
96 | |
97 | ml = m + sz - diff; |
98 | |
99 | mpx_loadl(m, ml, v->buf, v->len); |
100 | if (!chkscan(m, ml, v->buf, v->len, +1)) |
101 | ok = 0; |
102 | MPX_OCTETS(oct, m, ml); |
103 | mpx_storel(m, ml, d.buf, d.sz); |
104 | if (memcmp(d.buf, v->buf, oct) != 0) { |
105 | dumpbits("\n*** storel failed", d.buf, d.sz); |
106 | ok = 0; |
107 | } |
108 | |
109 | mpx_loadb(m, ml, v->buf, v->len); |
110 | if (!chkscan(m, ml, v->buf + v->len - 1, v->len, -1)) |
111 | ok = 0; |
112 | MPX_OCTETS(oct, m, ml); |
113 | mpx_storeb(m, ml, d.buf, d.sz); |
114 | if (memcmp(d.buf + d.sz - oct, v->buf + v->len - oct, oct) != 0) { |
115 | dumpbits("\n*** storeb failed", d.buf, d.sz); |
116 | ok = 0; |
117 | } |
118 | } |
119 | |
120 | if (!ok) |
121 | dumpbits("input data", v->buf, v->len); |
122 | |
123 | free(m); |
124 | dstr_destroy(&d); |
125 | return (ok); |
126 | } |
127 | |
128 | static int lsl(dstr *v) |
129 | { |
130 | mpw *a, *al; |
131 | int n = *(int *)v[1].buf; |
132 | mpw *c, *cl; |
133 | mpw *d, *dl; |
134 | int ok = 1; |
135 | |
136 | LOAD(a, al, &v[0]); |
137 | LOAD(c, cl, &v[2]); |
138 | ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS); |
139 | |
140 | mpx_lsl(d, dl, a, al, n); |
141 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
142 | fprintf(stderr, "\n*** lsl(%i) failed\n", n); |
143 | dumpmp(" a", a, al); |
144 | dumpmp("expected", c, cl); |
145 | dumpmp(" result", d, dl); |
146 | ok = 0; |
147 | } |
148 | |
149 | free(a); free(c); free(d); |
150 | return (ok); |
151 | } |
152 | |
153 | static int lsr(dstr *v) |
154 | { |
155 | mpw *a, *al; |
156 | int n = *(int *)v[1].buf; |
157 | mpw *c, *cl; |
158 | mpw *d, *dl; |
159 | int ok = 1; |
160 | |
161 | LOAD(a, al, &v[0]); |
162 | LOAD(c, cl, &v[2]); |
163 | ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS + 1); |
164 | |
165 | mpx_lsr(d, dl, a, al, n); |
166 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
167 | fprintf(stderr, "\n*** lsr(%i) failed\n", n); |
168 | dumpmp(" a", a, al); |
169 | dumpmp("expected", c, cl); |
170 | dumpmp(" result", d, dl); |
171 | ok = 0; |
172 | } |
173 | |
174 | free(a); free(c); free(d); |
175 | return (ok); |
176 | } |
177 | |
178 | static int uadd(dstr *v) |
179 | { |
180 | mpw *a, *al; |
181 | mpw *b, *bl; |
182 | mpw *c, *cl; |
183 | mpw *d, *dl; |
184 | int ok = 1; |
185 | |
186 | LOAD(a, al, &v[0]); |
187 | LOAD(b, bl, &v[1]); |
188 | LOAD(c, cl, &v[2]); |
189 | ALLOC(d, dl, MAX(al - a, bl - b) + 1); |
190 | |
191 | mpx_uadd(d, dl, a, al, b, bl); |
192 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
193 | fprintf(stderr, "\n*** uadd failed\n"); |
194 | dumpmp(" a", a, al); |
195 | dumpmp(" b", b, bl); |
196 | dumpmp("expected", c, cl); |
197 | dumpmp(" result", d, dl); |
198 | ok = 0; |
199 | } |
200 | |
201 | free(a); free(b); free(c); free(d); |
202 | return (ok); |
203 | } |
204 | |
205 | static int usub(dstr *v) |
206 | { |
207 | mpw *a, *al; |
208 | mpw *b, *bl; |
209 | mpw *c, *cl; |
210 | mpw *d, *dl; |
211 | int ok = 1; |
212 | |
213 | LOAD(a, al, &v[0]); |
214 | LOAD(b, bl, &v[1]); |
215 | LOAD(c, cl, &v[2]); |
216 | ALLOC(d, dl, al - a); |
217 | |
218 | mpx_usub(d, dl, a, al, b, bl); |
219 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
220 | fprintf(stderr, "\n*** usub failed\n"); |
221 | dumpmp(" a", a, al); |
222 | dumpmp(" b", b, bl); |
223 | dumpmp("expected", c, cl); |
224 | dumpmp(" result", d, dl); |
225 | ok = 0; |
226 | } |
227 | |
228 | free(a); free(b); free(c); free(d); |
229 | return (ok); |
230 | } |
231 | |
232 | static int umul(dstr *v) |
233 | { |
234 | mpw *a, *al; |
235 | mpw *b, *bl; |
236 | mpw *c, *cl; |
237 | mpw *d, *dl; |
238 | int ok = 1; |
239 | |
240 | LOAD(a, al, &v[0]); |
241 | LOAD(b, bl, &v[1]); |
242 | LOAD(c, cl, &v[2]); |
243 | ALLOC(d, dl, (al - a) + (bl - b)); |
244 | |
245 | mpx_umul(d, dl, a, al, b, bl); |
246 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
247 | fprintf(stderr, "\n*** umul failed\n"); |
248 | dumpmp(" a", a, al); |
249 | dumpmp(" b", b, bl); |
250 | dumpmp("expected", c, cl); |
251 | dumpmp(" result", d, dl); |
252 | ok = 0; |
253 | } |
254 | |
255 | free(a); free(b); free(c); free(d); |
256 | return (ok); |
257 | } |
258 | |
259 | static int usqr(dstr *v) |
260 | { |
261 | mpw *a, *al; |
262 | mpw *c, *cl; |
263 | mpw *d, *dl; |
264 | int ok = 1; |
265 | |
266 | LOAD(a, al, &v[0]); |
267 | LOAD(c, cl, &v[1]); |
268 | ALLOC(d, dl, 2 * (al - a)); |
269 | |
270 | mpx_usqr(d, dl, a, al); |
271 | if (MPX_UCMP(d, dl, !=, c, cl)) { |
272 | fprintf(stderr, "\n*** usqr failed\n"); |
273 | dumpmp(" a", a, al); |
274 | dumpmp("expected", c, cl); |
275 | dumpmp(" result", d, dl); |
276 | ok = 0; |
277 | } |
278 | |
279 | free(a); free(c); free(d); |
280 | return (ok); |
281 | } |
282 | |
283 | static int udiv(dstr *v) |
284 | { |
285 | mpw *a, *al; |
286 | mpw *b, *bl; |
287 | mpw *q, *ql; |
288 | mpw *r, *rl; |
289 | mpw *qq, *qql; |
290 | mpw *s, *sl; |
291 | int ok = 1; |
292 | |
293 | ALLOC(a, al, MPW_RQ(v[0].len) + 2); mpx_loadb(a, al, v[0].buf, v[0].len); |
294 | LOAD(b, bl, &v[1]); |
295 | LOAD(q, ql, &v[2]); |
296 | LOAD(r, rl, &v[3]); |
297 | ALLOC(qq, qql, al - a); |
298 | ALLOC(s, sl, 2 * (bl - b) + 2); |
299 | |
300 | mpx_udiv(qq, qql, a, al, b, bl, s, sl); |
301 | if (MPX_UCMP(qq, qql, !=, q, ql) || |
302 | MPX_UCMP(a, al, !=, r, rl)) { |
303 | fprintf(stderr, "\n*** udiv failed\n"); |
304 | dumpmp(" divisor", b, bl); |
305 | dumpmp("expect r", r, rl); |
306 | dumpmp("result r", a, al); |
307 | dumpmp("expect q", q, ql); |
308 | dumpmp("result q", qq, qql); |
309 | ok = 0; |
310 | } |
311 | |
312 | free(a); free(b); free(r); free(q); free(s); free(qq); |
313 | return (ok); |
314 | } |
315 | |
316 | static test_chunk defs[] = { |
317 | { "load-store", loadstore, { &type_hex, 0 } }, |
318 | { "lsl", lsl, { &type_hex, &type_int, &type_hex, 0 } }, |
319 | { "lsr", lsr, { &type_hex, &type_int, &type_hex, 0 } }, |
320 | { "uadd", uadd, { &type_hex, &type_hex, &type_hex, 0 } }, |
321 | { "usub", usub, { &type_hex, &type_hex, &type_hex, 0 } }, |
322 | { "umul", umul, { &type_hex, &type_hex, &type_hex, 0 } }, |
323 | { "usqr", usqr, { &type_hex, &type_hex, 0 } }, |
324 | { "udiv", udiv, { &type_hex, &type_hex, &type_hex, &type_hex, 0 } }, |
325 | { 0, 0, { 0 } } |
326 | }; |
327 | |
328 | int main(int argc, char *argv[]) |
329 | { |
330 | test_run(argc, argv, defs, SRCDIR"/tests/mpx"); |
331 | return (0); |
332 | } |