+static int loadstore(dstr *v)
+{
+ dstr d = DSTR_INIT;
+ size_t sz = MPW_RQ(v->len) * 2, diff;
+ mpw *m, *ml;
+ int ok = 1;
+
+ dstr_ensure(&d, v->len);
+ m = xmalloc(MPWS(sz));
+
+ for (diff = 0; diff < sz; diff += 5) {
+ size_t oct;
+
+ ml = m + sz - diff;
+
+ mpx_loadl(m, ml, v->buf, v->len);
+ if (!chkscan(m, ml, v->buf, v->len, +1))
+ ok = 0;
+ MPX_OCTETS(oct, m, ml);
+ mpx_storel(m, ml, d.buf, d.sz);
+ if (memcmp(d.buf, v->buf, oct) != 0) {
+ dumpbits("\n*** storel failed", d.buf, d.sz);
+ ok = 0;
+ }
+
+ mpx_loadb(m, ml, v->buf, v->len);
+ if (!chkscan(m, ml, v->buf + v->len - 1, v->len, -1))
+ ok = 0;
+ MPX_OCTETS(oct, m, ml);
+ mpx_storeb(m, ml, d.buf, d.sz);
+ if (memcmp(d.buf + d.sz - oct, v->buf + v->len - oct, oct) != 0) {
+ dumpbits("\n*** storeb failed", d.buf, d.sz);
+ ok = 0;
+ }
+ }
+
+ if (!ok)
+ dumpbits("input data", v->buf, v->len);
+
+ free(m);
+ dstr_destroy(&d);
+ return (ok);
+}
+
+static int lsl(dstr *v)
+{
+ mpw *a, *al;
+ int n = *(int *)v[1].buf;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(c, cl, &v[2]);
+ ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS);
+
+ mpx_lsl(d, dl, a, al, n);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** lsl(%i) failed\n", n);
+ dumpmp(" a", a, al);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(c); free(d);
+ return (ok);
+}
+
+static int lsr(dstr *v)
+{
+ mpw *a, *al;
+ int n = *(int *)v[1].buf;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(c, cl, &v[2]);
+ ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS + 1);
+
+ mpx_lsr(d, dl, a, al, n);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** lsr(%i) failed\n", n);
+ dumpmp(" a", a, al);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(c); free(d);
+ return (ok);
+}
+
+static int uadd(dstr *v)
+{
+ mpw *a, *al;
+ mpw *b, *bl;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(b, bl, &v[1]);
+ LOAD(c, cl, &v[2]);
+ ALLOC(d, dl, MAX(al - a, bl - b) + 1);
+
+ mpx_uadd(d, dl, a, al, b, bl);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** uadd failed\n");
+ dumpmp(" a", a, al);
+ dumpmp(" b", b, bl);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(b); free(c); free(d);
+ return (ok);
+}
+
+static int usub(dstr *v)
+{
+ mpw *a, *al;
+ mpw *b, *bl;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(b, bl, &v[1]);
+ LOAD(c, cl, &v[2]);
+ ALLOC(d, dl, al - a);
+
+ mpx_usub(d, dl, a, al, b, bl);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** usub failed\n");
+ dumpmp(" a", a, al);
+ dumpmp(" b", b, bl);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(b); free(c); free(d);
+ return (ok);
+}
+
+static int umul(dstr *v)
+{
+ mpw *a, *al;
+ mpw *b, *bl;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(b, bl, &v[1]);
+ LOAD(c, cl, &v[2]);
+ ALLOC(d, dl, (al - a) + (bl - b));
+
+ mpx_umul(d, dl, a, al, b, bl);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** umul failed\n");
+ dumpmp(" a", a, al);
+ dumpmp(" b", b, bl);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(b); free(c); free(d);
+ return (ok);
+}
+
+static int usqr(dstr *v)
+{
+ mpw *a, *al;
+ mpw *c, *cl;
+ mpw *d, *dl;
+ int ok = 1;
+
+ LOAD(a, al, &v[0]);
+ LOAD(c, cl, &v[1]);
+ ALLOC(d, dl, 2 * (al - a));
+
+ mpx_usqr(d, dl, a, al);
+ if (MPX_UCMP(d, dl, !=, c, cl)) {
+ fprintf(stderr, "\n*** usqr failed\n");
+ dumpmp(" a", a, al);
+ dumpmp("expected", c, cl);
+ dumpmp(" result", d, dl);
+ ok = 0;
+ }
+
+ free(a); free(c); free(d);
+ return (ok);
+}
+
+static int udiv(dstr *v)
+{
+ mpw *a, *al;
+ mpw *b, *bl;
+ mpw *q, *ql;
+ mpw *r, *rl;
+ mpw *qq, *qql;
+ mpw *s, *sl;
+ int ok = 1;
+
+ ALLOC(a, al, MPW_RQ(v[0].len) + 2); mpx_loadb(a, al, v[0].buf, v[0].len);
+ LOAD(b, bl, &v[1]);
+ LOAD(q, ql, &v[2]);
+ LOAD(r, rl, &v[3]);
+ ALLOC(qq, qql, al - a);
+ ALLOC(s, sl, (bl - b) + 1);
+
+ mpx_udiv(qq, qql, a, al, b, bl, s, sl);
+ if (MPX_UCMP(qq, qql, !=, q, ql) ||
+ MPX_UCMP(a, al, !=, r, rl)) {
+ fprintf(stderr, "\n*** udiv failed\n");
+ dumpmp(" divisor", b, bl);
+ dumpmp("expect r", r, rl);
+ dumpmp("result r", a, al);
+ dumpmp("expect q", q, ql);
+ dumpmp("result q", qq, qql);
+ ok = 0;
+ }
+
+ free(a); free(b); free(r); free(q); free(s); free(qq);
+ return (ok);
+}
+
+static test_chunk defs[] = {
+ { "load-store", loadstore, { &type_hex, 0 } },
+ { "lsl", lsl, { &type_hex, &type_int, &type_hex, 0 } },
+ { "lsr", lsr, { &type_hex, &type_int, &type_hex, 0 } },
+ { "uadd", uadd, { &type_hex, &type_hex, &type_hex, 0 } },
+ { "usub", usub, { &type_hex, &type_hex, &type_hex, 0 } },
+ { "umul", umul, { &type_hex, &type_hex, &type_hex, 0 } },
+ { "usqr", usqr, { &type_hex, &type_hex, 0 } },
+ { "udiv", udiv, { &type_hex, &type_hex, &type_hex, &type_hex, 0 } },
+ { 0, 0, { 0 } }
+};
+
+int main(int argc, char *argv[])
+{
+ test_run(argc, argv, defs, SRCDIR"/tests/mpx");
+ return (0);
+}
+
+
+#endif
+