4#include "native/config.h"
10namespace native::detail::x86_vaes {
11 template<isa<x86> Arch>
requires(Arch.has(x86_feature::aes) && Arch.has(x86_feature::avx))
13 __m128i vaesenc(__m128i state, __m128i key) noexcept {
14 return _mm_aesenc_si128(state, key);
17 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx))
19 __m256i vaesenc(__m256i state, __m256i key) noexcept {
20 return _mm256_aesenc_epi128(state, key);
23 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx512f))
25 __m512i vaesenc(__m512i state, __m512i key) noexcept {
26 return _mm512_aesenc_epi128(state, key);
29 template<isa<x86> Arch,
class... Args>
30 void vaesenc(Args...) =
delete;
32 template<isa<x86> Arch>
requires(Arch.has(x86_feature::aes) && Arch.has(x86_feature::avx))
34 __m128i vaesenclast(__m128i state, __m128i key) noexcept {
35 return _mm_aesenclast_si128(state, key);
38 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx))
40 __m256i vaesenclast(__m256i state, __m256i key) noexcept {
41 return _mm256_aesenclast_epi128(state, key);
44 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx512f))
46 __m512i vaesenclast(__m512i state, __m512i key) noexcept {
47 return _mm512_aesenclast_epi128(state, key);
50 template<isa<x86> Arch,
class... Args>
51 void vaesenclast(Args...) =
delete;
53 template<isa<x86> Arch>
requires(Arch.has(x86_feature::aes) && Arch.has(x86_feature::avx))
55 __m128i vaesdec(__m128i state, __m128i key) noexcept {
56 return _mm_aesdec_si128(state, key);
59 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx))
61 __m256i vaesdec(__m256i state, __m256i key) noexcept {
62 return _mm256_aesdec_epi128(state, key);
65 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx512f))
67 __m512i vaesdec(__m512i state, __m512i key) noexcept {
68 return _mm512_aesdec_epi128(state, key);
71 template<isa<x86> Arch,
class... Args>
72 void vaesdec(Args...) =
delete;
74 template<isa<x86> Arch>
requires(Arch.has(x86_feature::aes) && Arch.has(x86_feature::avx))
76 __m128i vaesdeclast(__m128i state, __m128i key) noexcept {
77 return _mm_aesdeclast_si128(state, key);
80 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx))
82 __m256i vaesdeclast(__m256i state, __m256i key) noexcept {
83 return _mm256_aesdeclast_epi128(state, key);
86 template<isa<x86> Arch>
requires(Arch.has(x86_feature::vaes) && Arch.has(x86_feature::avx512f))
88 __m512i vaesdeclast(__m512i state, __m512i key) noexcept {
89 return _mm512_aesdeclast_epi128(state, key);
92 template<isa<x86> Arch,
class... Args>
93 void vaesdeclast(Args...) =
delete;
98#include "native/x86/aes_constant.h"
100namespace native::detail::x86_vaes_constant {
103 template<
bool Inverse,
bool Last,
class V>
104 constexpr V round(V state, V key)
noexcept {
105 auto input = x86_aes_constant::lanes(state);
106 auto round_key = x86_aes_constant::lanes(key);
108 for (
unsigned base = 0; base < V::lanes; base += 16) {
109 std::array<std::uint8_t, 16> block{};
110 for (
unsigned column = 0; column < 4; ++column) {
111 for (
unsigned row = 0; row < 4; ++row) {
112 auto source = 4 * ((column + (Inverse ? 4 - row : row)) % 4) + row;
113 block[4 * column + row] = x86_aes_constant::substitute<Inverse>(input[base + source]);
116 if constexpr (!Last) {
117 block = x86_aes_constant::mix<Inverse>(block);
119 for (
unsigned i = 0; i < 16; ++i) {
120 result[base + i] = block[i] ^ round_key[base + i];
123 return V::load(result.data());
Compiler attributes for host code, with shader-safe shared modifiers.
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
#define native_const
[[const]] is not const
#define native_target(x)
this indicates a required feature set for the current multiversioned function.