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