#endif
#if defined(fmaddsub) && !defined(addsub)
-# define addsub(x, y) fmaddsub(x, broadcast(1), y)
+# ifdef __AVX512F__
+# define addsub(x, y) ({ \
+ vec_t t_; \
+ typeof(t_[0]) one_ = 1; \
+ asm ( "vfmaddsub231p" ELEM_SFX " %2%{1to%c4%}, %1, %0" \
+ : "=v" (t_) \
+ : "v" (x), "m" (one_), "0" (y), "i" (ELEM_COUNT) ); \
+ t_; \
+})
+# else
+# define addsub(x, y) fmaddsub(x, broadcast(1), y)
+# endif
#endif
int fma_test(void)
{
unsigned int i;
vec_t x, y, z, src, inv, one;
+#ifdef __AVX512F__
+ typeof(one[0]) one_ = 1;
+#endif
for ( i = 0; i < ELEM_COUNT; ++i )
{
one[i] = 1;
}
+#ifdef __AVX512F__
+# define one one_
+#endif
+
x = (src + one) * inv;
y = (src - one) * inv;
touch(src);
x = src + inv;
y = src - inv;
touch(inv);
+ touch(one);
z = src * one + inv;
if ( !eq(x, z) ) return __LINE__;
touch(inv);
+ touch(one);
z = -src * one - inv;
if ( !eq(-x, z) ) return __LINE__;
touch(inv);
+ touch(one);
z = src * one - inv;
if ( !eq(y, z) ) return __LINE__;
touch(inv);
+ touch(one);
z = -src * one + inv;
if ( !eq(-y, z) ) return __LINE__;
touch(inv);
+#undef one
+
#if defined(addsub) && defined(fmaddsub)
x = addsub(src * inv, one);
y = addsub(src * inv, -one);
})
# endif
# endif
+#elif VEC_SIZE == 64
+# if FLOAT_SIZE == 4
+# define dup_hi(x) B(movshdup, _mask, x, undef(), ~0)
+# define dup_lo(x) B(movsldup, _mask, x, undef(), ~0)
+# elif FLOAT_SIZE == 8
+# define dup_lo(x) B(movddup, _mask, x, undef(), ~0)
+# endif
#endif
#if VEC_SIZE == 16 && defined(__SSSE3__) && !defined(__AVX512VL__)
# if INT_SIZE == 1