1 #define UINT_SIZE 1
2 
3 #include "simd.h"
4 ENTRY(aes_test);
5 
6 #if VEC_SIZE == 16
7 # define AES(op, a...) __builtin_ia32_vaes ## op ## _v16qi(a)
8 # define imc(x) ((vec_t)__builtin_ia32_aesimc128((vdi_t)(x)))
9 #elif VEC_SIZE == 32
10 # define AES(op, a...) __builtin_ia32_vaes ## op ## _v32qi(a)
11 # define imc(x) ({ \
12     vec_t r_; \
13     unsigned char __attribute__((vector_size(16))) t_; \
14     asm ( "vaesimc (%3), %x0\n\t" \
15           "vaesimc 16(%3), %1\n\t" \
16           "vinserti128 $1, %1, %0, %0" \
17           : "=&v" (r_), "=&v" (t_) \
18           : "m" (x), "r" (&(x)) ); \
19     r_; \
20 })
21 #elif VEC_SIZE == 64
22 # define AES(op, a...) __builtin_ia32_vaes ## op ## _v64qi(a)
23 # define imc(x) ({ \
24     vec_t r_; \
25     unsigned char __attribute__((vector_size(16))) t_; \
26     asm ( "vaesimc (%3), %x0\n\t" \
27           "vaesimc 1*16(%3), %1\n\t" \
28           "vinserti32x4 $1, %1, %0, %0\n\t" \
29           "vaesimc 2*16(%3), %1\n\t" \
30           "vinserti32x4 $2, %1, %0, %0\n\t" \
31           "vaesimc 3*16(%3), %1\n\t" \
32           "vinserti32x4 $3, %1, %0, %0" \
33           : "=&v" (r_), "=&v" (t_) \
34           : "m" (x), "r" (&(x)) ); \
35     r_; \
36 })
37 #endif
38 
39 #ifdef __AVX512BW__
40 # define ALL_TRUE (~0ULL >> (64 - ELEM_COUNT))
41 # define eq(x, y) (B(pcmpeqb, _mask, (vqi_t)(x), (vqi_t)(y), -1) == ALL_TRUE)
42 # define aes(op, x, y) ((vec_t)AES(op, (vqi_t)(x), (vqi_t)(y)))
43 #else
44 # if defined(__AVX2__) && VEC_SIZE == 32
45 #  define to_bool(cmp) B(ptestc, , cmp, (vdi_t){} == 0)
46 #  define aes(op, x, y) ((vec_t)AES(op, (vqi_t)(x), (vqi_t)(y)))
47 # else
48 #  define to_bool(cmp) (__builtin_ia32_pmovmskb128(cmp) == 0xffff)
49 #  define aes(op, x, y) ((vec_t)__builtin_ia32_aes ## op ## 128((vdi_t)(x), (vdi_t)(y)))
50 # endif
51 # define eq(x, y) to_bool((x) == (y))
52 #endif
53 
aes_test(void)54 int aes_test(void)
55 {
56     unsigned int i;
57     vec_t src, zero = {};
58 
59     for ( i = 0; i < ELEM_COUNT; ++i )
60         src[i] = i;
61 
62     do {
63         vec_t x, y;
64 
65         touch(src);
66         x = imc(src);
67         touch(src);
68 
69         touch(zero);
70         y = aes(enclast, src, zero);
71         touch(zero);
72         y = aes(dec, y, zero);
73 
74         if ( !eq(x, y) ) return __LINE__;
75 
76         touch(zero);
77         x = aes(declast, src, zero);
78         touch(zero);
79         y = aes(enc, x, zero);
80         touch(y);
81         x = imc(y);
82 
83         if ( !eq(x, src) ) return __LINE__;
84 
85 #if VEC_SIZE == 16
86         touch(src);
87         x = (vec_t)__builtin_ia32_aeskeygenassist128((vdi_t)src, 0);
88         touch(src);
89         y = (vec_t)__builtin_ia32_pshufb128((vqi_t)x,
90                                             (vqi_t){  7,  4,  5,  6,
91                                                       1,  2,  3,  0,
92                                                      15, 12, 13, 14,
93                                                       9, 10, 11,  8 });
94         if ( !eq(x, y) ) return __LINE__;
95 #endif
96 
97         src += ELEM_COUNT;
98         i += ELEM_COUNT;
99     } while ( i <= 256 );
100 
101     return 0;
102 }
103