Initialize the register dumping machinery while testing assembler code.
[catacomb] / math / mpx-mul4-test.c
index 883c4fc..85a1532 100644 (file)
 
 #include "config.h"
 
+#ifdef ENABLE_ASM_DEBUG
+#  include "regdump.h"
+#endif
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -80,7 +84,9 @@ typedef struct { mpd w[6]; } carry;
   _(dmul4, NIL,  CARRY, P128, P128, P128, P128, P128, NIL,  CARRY)     \
   _(dmla4, P128, CARRY, P128, P128, P128, P128, P128, NIL,  CARRY)     \
   _(mul4,  NIL,         CARRY, NIL,  P128, NIL,  P128, P128, NIL,  CARRY)      \
+  _(mul4zc,NIL,         NIL,   NIL,  P128, NIL,  P128, P128, NIL,  CARRY)      \
   _(mla4,  P128, CARRY, NIL,  P128, NIL,  P128, P128, NIL,  CARRY)     \
+  _(mla4zc,P128, NIL,  NIL,  P128, NIL,  P128, P128, NIL,  CARRY)      \
   _(mmul4, NIL,         NIL,   P128, P128, P128, P128, P128, X128, CARRY)      \
   _(mmla4, P128, NIL,  P128, P128, P128, P128, P128, X128, CARRY)      \
   _(mont4, P128, NIL,  NIL,  P128, NIL,  P128, P128, X128, CARRY)
@@ -105,7 +111,37 @@ TESTOPS(DECLSTUB)
 
 /*----- Conversion functions ----------------------------------------------*/
 
-#define DEFTYPE(ty, ld, st, nby)                                       \
+static mp *combine_mpw(mp *d, const mpw *v, size_t n, unsigned off)
+{
+  size_t i;
+  unsigned o;
+  mp m, *t = d;
+  mpw w[1];
+
+  d = MP_ZERO;
+  for (i = 0, o = 0; i < n; i++, o += off) {
+    w[0] = v[i]; mp_build(&m, w, w + 1);
+    t = mp_lsl(t, &m, o); d = mp_add(d, d, t);
+  }
+  mp_drop(t); return (d);
+}
+
+static mp *combine_mpd(mp *d, const mpd *v, size_t n, unsigned off)
+{
+  size_t i;
+  unsigned o;
+  mp m, *t = d;
+  mpw w[2];
+
+  d = MP_ZERO;
+  for (i = 0, o = 0; i < n; i++, o += off) {
+    w[0] = MPW(v[i]); w[1] = MPW(v[i] >> MPW_BITS); mp_build(&m, w, w + 2);
+    t = mp_lsl(t, &m, o); d = mp_add(d, d, t);
+  }
+  mp_drop(t); return (d);
+}
+
+#define DEFTYPE(ty, ld, st, nby, combfn, off)                          \
                                                                        \
   static void cvt_##ty(const char *buf, dstr *d)                       \
   {                                                                    \
@@ -116,7 +152,7 @@ TESTOPS(DECLSTUB)
                                                                        \
     type_hex.cvt(buf, &dd);                                            \
     if (dd.len != N(x->w)*nby) die(1, "invalid length for " #ty);      \
-    dstr_ensure(d, sizeof(*x));                                                \
+    dstr_ensure(d, sizeof(*x)); d->len = sizeof(*x);                   \
     x = (ty *)d->buf; p = (const octet *)dd.buf;                       \
     for (i = 0; i < N(x->w); i++) { x->w[i] = ld(p); p += nby; }       \
     dstr_destroy(&dd);                                                 \
@@ -127,6 +163,7 @@ TESTOPS(DECLSTUB)
     dstr dd = DSTR_INIT;                                               \
     int i;                                                             \
     const ty *x = (const ty *)d->buf;                                  \
+    mp *xx = combfn(MP_NEW, x->w, N(x->w), off);                       \
     octet *p;                                                          \
                                                                        \
     dstr_ensure(&dd, N(x->w)*nby); p = (octet *)dd.buf;                        \
@@ -134,22 +171,26 @@ TESTOPS(DECLSTUB)
     dd.len = N(x->w)*nby;                                              \
     type_hex.dump(&dd, fp);                                            \
     dstr_destroy(&dd);                                                 \
+                                                                       \
+    fputs(" = 0x", fp); mp_writefile(xx, fp, 16);                      \
+    fputs(" = ", fp); mp_writefile(xx, fp, 10);                                \
+    MP_DROP(xx);                                                       \
   }                                                                    \
                                                                        \
   static int eq_##ty(const ty *x, const ty *y)                         \
   {                                                                    \
-    int i;                                                             \
-                                                                       \
-    for (i = 0; i < N(x->w); i++)                                      \
-      if (x->w[i] != y->w[i]) return (0);                              \
-    return (1);                                                                \
+    mp *xx = combfn(MP_NEW, x->w, N(x->w), off),                       \
+      *yy = combfn(MP_NEW, y->w, N(y->w), off);                                \
+    int rc = MP_EQ(xx, yy);                                            \
+    MP_DROP(xx); MP_DROP(yy);                                          \
+    return (rc);                                                       \
   }                                                                    \
                                                                        \
   static const struct test_type type_##ty = { cvt_##ty, dump_##ty };
 
-DEFTYPE(p128, LDW, STW, NWBY)
-DEFTYPE(x128, LDW, STW, NWBY)
-DEFTYPE(carry, LDD, STD, NDBY)
+DEFTYPE(p128, LDW, STW, NWBY, combine_mpw, MPW_BITS)
+DEFTYPE(x128, LDW, STW, NWBY, combine_mpw, MPW_BITS/2)
+DEFTYPE(carry, LDD, STD, NDBY, combine_mpd, MPW_BITS/2)
 
 /*----- Test functions ----------------------------------------------------*/
 
@@ -282,9 +323,12 @@ static test_chunk tests[] = {
 int main(int argc, char *argv[])
 {
   sub_init();
+#ifdef ENABLE_ASM_DEBUG
+  regdump_init();
+#endif
   if (!cpu_features_p())
     { fprintf(stderr, "required cpu feature not available\n"); exit(77); }
-  test_run(argc, argv, tests, SRCDIR "/t/mul4");
+  test_run(argc, argv, tests, SRCDIR "/t/mpx-mul4");
   return (0);
 }