#include "config.h"
+#ifdef ENABLE_ASM_DEBUG
+# include "regdump.h"
+#endif
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static int cpu_features_p(void) { return (cpu_feature_p(CPUFEAT_X86_SSE2)); }
#endif
+#if CPUFAM_ARMEL
+# define VARIANT _arm_neon
+# define REPR_32
+static int cpu_features_p(void) { return (cpu_feature_p(CPUFEAT_ARM_NEON)); }
+#endif
+
+#if CPUFAM_ARM64
+# define VARIANT _arm64_simd
+# define REPR_32
+static int cpu_features_p(void) { return (1); }
+#endif
+
#ifndef VARIANT
# error "Unsupported CPU family."
#endif
/*----- 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) \
{ \
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; \
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 ----------------------------------------------------*/
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/mpx-mul4");