1 #define UINT_SIZE 1
2 
3 #include "simd.h"
4 ENTRY(gf_test);
5 
6 #if VEC_SIZE == 16
7 # define GF(op, s, a...) __builtin_ia32_vgf2p8 ## op ## _v16qi ## s(a)
8 #elif VEC_SIZE == 32
9 # define GF(op, s, a...) __builtin_ia32_vgf2p8 ## op ## _v32qi ## s(a)
10 #elif VEC_SIZE == 64
11 # define GF(op, s, a...) __builtin_ia32_vgf2p8 ## op ## _v64qi ## s(a)
12 #endif
13 
14 #ifdef __AVX512BW__
15 # define ALL_TRUE (~0ULL >> (64 - ELEM_COUNT))
16 # define eq(x, y) (B(pcmpeqb, _mask, (vqi_t)(x), (vqi_t)(y), -1) == ALL_TRUE)
17 # define mul(x, y) GF(mulb, _mask, (vqi_t)(x), (vqi_t)(y), (vqi_t)undef(), ~0)
18 # define transform(m, dir, x, c) ({ \
19     vec_t t_; \
20     asm ( "vgf2p8affine" #dir "qb %[imm], %[matrix]%{1to%c[n]%}, %[src], %[dst]" \
21           : [dst] "=v" (t_) \
22           : [matrix] "m" (m), [src] "v" (x), [imm] "i" (c), [n] "i" (VEC_SIZE / 8) ); \
23     t_; \
24 })
25 #else
26 # if defined(__AVX2__)
27 #  define bcstq(x) ({ \
28     vdi_t t_; \
29     asm ( "vpbroadcastq %1, %0" : "=x" (t_) : "m" (x) ); \
30     t_; \
31 })
32 #  define to_bool(cmp) B(ptestc, , cmp, (vdi_t){} == 0)
33 # else
34 #  define bcstq(x) ((vdi_t){x, x})
35 #  define to_bool(cmp) (__builtin_ia32_pmovmskb128(cmp) == 0xffff)
36 # endif
37 # define eq(x, y) to_bool((x) == (y))
38 # define mul(x, y) GF(mulb, , (vqi_t)(x), (vqi_t)(y))
39 # define transform(m, dir, x, c) ({ \
40     vdi_t m_ = bcstq(m); \
41     touch(m_); \
42     ((vec_t)GF(affine ## dir ## qb, , (vqi_t)(x), (vqi_t)m_, c)); \
43 })
44 #endif
45 
46 const unsigned __attribute__((mode(DI))) ident = 0x0102040810204080ULL;
47 
gf_test(void)48 int gf_test(void)
49 {
50     unsigned int i;
51     vec_t src, one;
52 
53     for ( i = 0; i < ELEM_COUNT; ++i )
54     {
55         src[i] = i;
56         one[i] = 1;
57     }
58 
59     /* Special case for first iteration. */
60     one[0] = 0;
61 
62     do {
63         vec_t inv = transform(ident, inv, src, 0);
64 
65         touch(src);
66         touch(inv);
67         if ( !eq(mul(src, inv), one) ) return __LINE__;
68 
69         touch(src);
70         touch(inv);
71         if ( !eq(mul(inv, src), one) ) return __LINE__;
72 
73         one[0] = 1;
74 
75         src += ELEM_COUNT;
76         i += ELEM_COUNT;
77     } while ( i < 256 );
78 
79     return 0;
80 }
81