1 //! AES New Instructions (AES-NI)
3 //! The intrinsics here correspond to those in the `wmmintrin.h` C header.
5 //! The reference is [Intel 64 and IA-32 Architectures Software Developer's
6 //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref].
8 //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
10 use crate::core_arch
::x86
::__m128i
;
13 use stdarch_test
::assert_instr
;
15 #[allow(improper_ctypes)]
17 #[link_name = "llvm.x86.aesni.aesdec"]
18 fn aesdec(a
: __m128i
, round_key
: __m128i
) -> __m128i
;
19 #[link_name = "llvm.x86.aesni.aesdeclast"]
20 fn aesdeclast(a
: __m128i
, round_key
: __m128i
) -> __m128i
;
21 #[link_name = "llvm.x86.aesni.aesenc"]
22 fn aesenc(a
: __m128i
, round_key
: __m128i
) -> __m128i
;
23 #[link_name = "llvm.x86.aesni.aesenclast"]
24 fn aesenclast(a
: __m128i
, round_key
: __m128i
) -> __m128i
;
25 #[link_name = "llvm.x86.aesni.aesimc"]
26 fn aesimc(a
: __m128i
) -> __m128i
;
27 #[link_name = "llvm.x86.aesni.aeskeygenassist"]
28 fn aeskeygenassist(a
: __m128i
, imm8
: u8) -> __m128i
;
31 /// Performs one round of an AES decryption flow on data (state) in `a`.
33 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128)
35 #[target_feature(enable = "aes")]
36 #[cfg_attr(test, assert_instr(aesdec))]
37 #[stable(feature = "simd_x86", since = "1.27.0")]
38 pub unsafe fn _mm_aesdec_si128(a
: __m128i
, round_key
: __m128i
) -> __m128i
{
42 /// Performs the last round of an AES decryption flow on data (state) in `a`.
44 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128)
46 #[target_feature(enable = "aes")]
47 #[cfg_attr(test, assert_instr(aesdeclast))]
48 #[stable(feature = "simd_x86", since = "1.27.0")]
49 pub unsafe fn _mm_aesdeclast_si128(a
: __m128i
, round_key
: __m128i
) -> __m128i
{
50 aesdeclast(a
, round_key
)
53 /// Performs one round of an AES encryption flow on data (state) in `a`.
55 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128)
57 #[target_feature(enable = "aes")]
58 #[cfg_attr(test, assert_instr(aesenc))]
59 #[stable(feature = "simd_x86", since = "1.27.0")]
60 pub unsafe fn _mm_aesenc_si128(a
: __m128i
, round_key
: __m128i
) -> __m128i
{
64 /// Performs the last round of an AES encryption flow on data (state) in `a`.
66 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128)
68 #[target_feature(enable = "aes")]
69 #[cfg_attr(test, assert_instr(aesenclast))]
70 #[stable(feature = "simd_x86", since = "1.27.0")]
71 pub unsafe fn _mm_aesenclast_si128(a
: __m128i
, round_key
: __m128i
) -> __m128i
{
72 aesenclast(a
, round_key
)
75 /// Performs the `InvMixColumns` transformation on `a`.
77 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesimc_si128)
79 #[target_feature(enable = "aes")]
80 #[cfg_attr(test, assert_instr(aesimc))]
81 #[stable(feature = "simd_x86", since = "1.27.0")]
82 pub unsafe fn _mm_aesimc_si128(a
: __m128i
) -> __m128i
{
86 /// Assist in expanding the AES cipher key.
88 /// Assist in expanding the AES cipher key by computing steps towards
89 /// generating a round key for encryption cipher using data from `a` and an
90 /// 8-bit round constant `IMM8`.
92 /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aeskeygenassist_si128)
94 #[target_feature(enable = "aes")]
95 #[cfg_attr(test, assert_instr(aeskeygenassist, IMM8 = 0))]
96 #[rustc_legacy_const_generics(1)]
97 #[stable(feature = "simd_x86", since = "1.27.0")]
98 pub unsafe fn _mm_aeskeygenassist_si128
<const IMM8
: i32>(a
: __m128i
) -> __m128i
{
99 static_assert_uimm_bits
!(IMM8
, 8);
100 aeskeygenassist(a
, IMM8
as u8)
105 // The constants in the tests below are just bit patterns. They should not
106 // be interpreted as integers; signedness does not make sense for them, but
107 // __m128i happens to be defined in terms of signed integers.
108 #![allow(overflowing_literals)]
110 use stdarch_test
::simd_test
;
112 use crate::core_arch
::x86
::*;
114 #[simd_test(enable = "aes")]
115 unsafe fn test_mm_aesdec_si128() {
116 // Constants taken from https://msdn.microsoft.com/en-us/library/cc664949.aspx.
117 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
118 let k
= _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
119 let e
= _mm_set_epi64x(0x044e4f5176fec48f, 0xb57ecfa381da39ee);
120 let r
= _mm_aesdec_si128(a
, k
);
121 assert_eq_m128i(r
, e
);
124 #[simd_test(enable = "aes")]
125 unsafe fn test_mm_aesdeclast_si128() {
126 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714178.aspx.
127 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
128 let k
= _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
129 let e
= _mm_set_epi64x(0x36cad57d9072bf9e, 0xf210dd981fa4a493);
130 let r
= _mm_aesdeclast_si128(a
, k
);
131 assert_eq_m128i(r
, e
);
134 #[simd_test(enable = "aes")]
135 unsafe fn test_mm_aesenc_si128() {
136 // Constants taken from https://msdn.microsoft.com/en-us/library/cc664810.aspx.
137 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
138 let k
= _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
139 let e
= _mm_set_epi64x(0x16ab0e57dfc442ed, 0x28e4ee1884504333);
140 let r
= _mm_aesenc_si128(a
, k
);
141 assert_eq_m128i(r
, e
);
144 #[simd_test(enable = "aes")]
145 unsafe fn test_mm_aesenclast_si128() {
146 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714136.aspx.
147 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
148 let k
= _mm_set_epi64x(0x1133557799bbddff, 0x0022446688aaccee);
149 let e
= _mm_set_epi64x(0xb6dd7df25d7ab320, 0x4b04f98cf4c860f8);
150 let r
= _mm_aesenclast_si128(a
, k
);
151 assert_eq_m128i(r
, e
);
154 #[simd_test(enable = "aes")]
155 unsafe fn test_mm_aesimc_si128() {
156 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714195.aspx.
157 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
158 let e
= _mm_set_epi64x(0xc66c82284ee40aa0, 0x6633441122770055);
159 let r
= _mm_aesimc_si128(a
);
160 assert_eq_m128i(r
, e
);
163 #[simd_test(enable = "aes")]
164 unsafe fn test_mm_aeskeygenassist_si128() {
165 // Constants taken from https://msdn.microsoft.com/en-us/library/cc714138.aspx.
166 let a
= _mm_set_epi64x(0x0123456789abcdef, 0x8899aabbccddeeff);
167 let e
= _mm_set_epi64x(0x857c266b7c266e85, 0xeac4eea9c4eeacea);
168 let r
= _mm_aeskeygenassist_si128
::<5>(a
);
169 assert_eq_m128i(r
, e
);