native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.x86.gfni.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3#include "native/isa_import.h"
4#include "native/x86/gfni.h"
5#include "native/x86/integer_constant.h"
6export module native.x86.gfni;
7export import native.x86.features;
8export import native.simd;
9// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
10#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
11export namespace native {
32
33 // 128-bit registers.
35 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni))
37 constexpr simd<std::uint8_t, 16, Arch> gf2p8mulb(simd<std::uint8_t, 16, Arch> a, simd<std::uint8_t, 16, Arch> b) noexcept {
38 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0}); }
39 else {
40 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8mulb<Arch>(a.to_native(), b.to_native()));
41 }
42 }
43
45 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Imm8 <= 255)
48 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0}); }
49 else {
50 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
51 }
52 }
53
55 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Imm8 <= 255)
58 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0}); }
59 else {
60 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
61 }
62 }
63
65 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
66 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
69 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset()); }
70 else {
71 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8mulb_mask<Arch>(src.to_native(), k.to_bitset(), a.to_native(), b.to_native()));
72 }
73 }
74
76 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
77 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
80 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 16, Arch>{}, k.to_bitset()); }
81 else {
82 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8mulb_maskz<Arch>(k.to_bitset(), a.to_native(), b.to_native()));
83 }
84 }
85
87 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
88 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
91 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset()); }
92 else {
93 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
94 }
95 }
96
98 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
99 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
102 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 16, Arch>{}, k.to_bitset()); }
103 else {
104 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
105 }
106 }
107
109 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
110 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
113 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset()); }
114 else {
115 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
116 }
117 }
118
120 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
121 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
124 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 16, Arch>{}, k.to_bitset()); }
125 else {
126 return simd<std::uint8_t, 16, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
127 }
128 }
129
130
131 // 256-bit registers.
133 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx))
136 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0}); }
137 else {
138 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8mulb<Arch>(a.to_native(), b.to_native()));
139 }
140 }
141
143 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx) && Imm8 <= 255)
146 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0}); }
147 else {
148 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
149 }
150 }
151
153 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx) && Imm8 <= 255)
156 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0}); }
157 else {
158 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
159 }
160 }
161
163 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
164 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
167 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset()); }
168 else {
169 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8mulb_mask<Arch>(src.to_native(), k.to_bitset(), a.to_native(), b.to_native()));
170 }
171 }
172
174 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
175 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
178 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 32, Arch>{}, k.to_bitset()); }
179 else {
180 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8mulb_maskz<Arch>(k.to_bitset(), a.to_native(), b.to_native()));
181 }
182 }
183
185 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
186 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
189 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset()); }
190 else {
191 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
192 }
193 }
194
196 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
197 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
200 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 32, Arch>{}, k.to_bitset()); }
201 else {
202 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
203 }
204 }
205
207 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
208 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
211 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset()); }
212 else {
213 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
214 }
215 }
216
218 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
219 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
222 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 32, Arch>{}, k.to_bitset()); }
223 else {
224 return simd<std::uint8_t, 32, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
225 }
226 }
227
228
229 // 512-bit registers.
231 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f))
234 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0}); }
235 else {
236 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8mulb<Arch>(a.to_native(), b.to_native()));
237 }
238 }
239
241 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) && Imm8 <= 255)
244 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0}); }
245 else {
246 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
247 }
248 }
249
251 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) && Imm8 <= 255)
254 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0}); }
255 else {
256 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb<Arch, Imm8>(a.to_native(), matrix.to_native()));
257 }
258 }
259
261 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
262 Arch.has(x86_feature::avx512bw))
265 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset()); }
266 else {
267 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8mulb_mask<Arch>(src.to_native(), k.to_bitset(), a.to_native(), b.to_native()));
268 }
269 }
270
272 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
273 Arch.has(x86_feature::avx512bw))
276 if consteval { return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 64, Arch>{}, k.to_bitset()); }
277 else {
278 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8mulb_maskz<Arch>(k.to_bitset(), a.to_native(), b.to_native()));
279 }
280 }
281
283 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
284 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
287 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset()); }
288 else {
289 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
290 }
291 }
292
294 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
295 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
298 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 64, Arch>{}, k.to_bitset()); }
299 else {
300 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
301 }
302 }
303
305 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
306 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
309 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset()); }
310 else {
311 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_mask<Arch, Imm8>(src.to_native(), k.to_bitset(), a.to_native(), matrix.to_native()));
312 }
313 }
314
316 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
317 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
320 if consteval { return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 64, Arch>{}, k.to_bitset()); }
321 else {
322 return simd<std::uint8_t, 64, Arch>::from_native(detail::x86_gfni::gf2p8affineinvqb_maskz<Arch, Imm8>(k.to_bitset(), a.to_native(), matrix.to_native()));
323 }
324 }
325
327 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni))) &&
328 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
330 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0});
331 }
332
334 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni))) && Imm8 <= 255 &&
335 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
337 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0});
338 }
339
341 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni))) && Imm8 <= 255 &&
342 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
344 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0});
345 }
346
348 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
349 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) &&
350 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
352 return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset());
353 }
354
356 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
357 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) &&
358 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
360 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 16, Arch>{}, k.to_bitset());
361 }
362
364 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
365 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
366 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
367 native_nodiscard consteval simd<std::uint8_t, 16, Arch> gf2p8affineqb_mask(simd<std::uint8_t, 16, Arch> src, predicate<16, Arch> k, simd<std::uint8_t, 16, Arch> a, simd<std::uint64_t, 2, Arch> matrix) noexcept {
368 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset());
369 }
370
372 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
373 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
374 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
375 native_nodiscard consteval simd<std::uint8_t, 16, Arch> gf2p8affineqb_maskz(predicate<16, Arch> k, simd<std::uint8_t, 16, Arch> a, simd<std::uint64_t, 2, Arch> matrix) noexcept {
376 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 16, Arch>{}, k.to_bitset());
377 }
378
380 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
381 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
382 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
383 native_nodiscard consteval simd<std::uint8_t, 16, Arch> gf2p8affineinvqb_mask(simd<std::uint8_t, 16, Arch> src, predicate<16, Arch> k, simd<std::uint8_t, 16, Arch> a, simd<std::uint64_t, 2, Arch> matrix) noexcept {
384 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset());
385 }
386
388 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
389 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
390 requires { sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::uint64_t, 2, Arch>); })
391 native_nodiscard consteval simd<std::uint8_t, 16, Arch> gf2p8affineinvqb_maskz(predicate<16, Arch> k, simd<std::uint8_t, 16, Arch> a, simd<std::uint64_t, 2, Arch> matrix) noexcept {
392 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 16, Arch>{}, k.to_bitset());
393 }
394
396 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx))) &&
397 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
399 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0});
400 }
401
403 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx))) && Imm8 <= 255 &&
404 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
405 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineqb(simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
406 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0});
407 }
408
410 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx))) && Imm8 <= 255 &&
411 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
412 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineinvqb(simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
413 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0});
414 }
415
417 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
418 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) &&
419 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
421 return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset());
422 }
423
425 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
426 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) &&
427 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
429 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 32, Arch>{}, k.to_bitset());
430 }
431
433 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
434 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
435 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
436 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineqb_mask(simd<std::uint8_t, 32, Arch> src, predicate<32, Arch> k, simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
437 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset());
438 }
439
441 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
442 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
443 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
444 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineqb_maskz(predicate<32, Arch> k, simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
445 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 32, Arch>{}, k.to_bitset());
446 }
447
449 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
450 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
451 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
452 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineinvqb_mask(simd<std::uint8_t, 32, Arch> src, predicate<32, Arch> k, simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
453 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset());
454 }
455
457 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
458 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))) && Imm8 <= 255 &&
459 requires { sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::uint64_t, 4, Arch>); })
460 native_nodiscard consteval simd<std::uint8_t, 32, Arch> gf2p8affineinvqb_maskz(predicate<32, Arch> k, simd<std::uint8_t, 32, Arch> a, simd<std::uint64_t, 4, Arch> matrix) noexcept {
461 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 32, Arch>{}, k.to_bitset());
462 }
463
465 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f))) &&
466 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
468 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0});
469 }
470
472 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f))) && Imm8 <= 255 &&
473 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
474 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineqb(simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
475 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0});
476 }
477
479 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f))) && Imm8 <= 255 &&
480 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
481 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineinvqb(simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
482 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0});
483 }
484
486 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
487 Arch.has(x86_feature::avx512bw))) &&
488 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
490 return detail::x86_instruction_constant::field_multiply(a, b, src, k.to_bitset());
491 }
492
494 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
495 Arch.has(x86_feature::avx512bw))) &&
496 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
498 return detail::x86_instruction_constant::field_multiply(a, b, simd<std::uint8_t, 64, Arch>{}, k.to_bitset());
499 }
500
502 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
503 Arch.has(x86_feature::avx512bw))) && Imm8 <= 255 &&
504 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
505 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineqb_mask(simd<std::uint8_t, 64, Arch> src, predicate<64, Arch> k, simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
506 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, src, k.to_bitset());
507 }
508
510 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
511 Arch.has(x86_feature::avx512bw))) && Imm8 <= 255 &&
512 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
513 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineqb_maskz(predicate<64, Arch> k, simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
514 return detail::x86_instruction_constant::field_affine<Imm8, false>(a, matrix, simd<std::uint8_t, 64, Arch>{}, k.to_bitset());
515 }
516
518 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
519 Arch.has(x86_feature::avx512bw))) && Imm8 <= 255 &&
520 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
521 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineinvqb_mask(simd<std::uint8_t, 64, Arch> src, predicate<64, Arch> k, simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
522 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, src, k.to_bitset());
523 }
524
526 template<isa<x86> Arch, unsigned Imm8> requires(!((Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
527 Arch.has(x86_feature::avx512bw))) && Imm8 <= 255 &&
528 requires { sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::uint64_t, 8, Arch>); })
529 native_nodiscard consteval simd<std::uint8_t, 64, Arch> gf2p8affineinvqb_maskz(predicate<64, Arch> k, simd<std::uint8_t, 64, Arch> a, simd<std::uint64_t, 8, Arch> matrix) noexcept {
530 return detail::x86_instruction_constant::field_affine<Imm8, true>(a, matrix, simd<std::uint8_t, 64, Arch>{}, k.to_bitset());
531 }
532
533 // Reject implicit register conversions, mixed tags and wrong element types.
535 template<isa<x86> Arch, class... Args>
536 void gf2p8mulb(Args...) = delete;
538 template<isa<x86> Arch, unsigned Imm8, class... Args>
539 void gf2p8affineqb(Args...) = delete;
541 template<isa<x86> Arch, unsigned Imm8, class... Args>
542 void gf2p8affineinvqb(Args...) = delete;
544 template<isa<x86> Arch, class... Args>
545 void gf2p8mulb_mask(Args...) = delete;
547 template<isa<x86> Arch, class... Args>
548 void gf2p8mulb_maskz(Args...) = delete;
550 template<isa<x86> Arch, unsigned Imm8, class... Args>
551 void gf2p8affineqb_mask(Args...) = delete;
553 template<isa<x86> Arch, unsigned Imm8, class... Args>
554 void gf2p8affineqb_maskz(Args...) = delete;
556 template<isa<x86> Arch, unsigned Imm8, class... Args>
557 void gf2p8affineinvqb_mask(Args...) = delete;
559 template<isa<x86> Arch, unsigned Imm8, class... Args>
560 void gf2p8affineinvqb_maskz(Args...) = delete;
561
563}
564#endif
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_const
[[const]] is not const
Definition attributes.h:108
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
Definition attributes.h:476
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineinvqb_maskz(predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Zero inactive bytes after gf2p8affineinvqb.
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineqb_mask(simd< std::uint8_t, 16, Arch > src, predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Merge inactive bytes from src after gf2p8affineqb.
constexpr simd< std::uint8_t, 16, Arch > gf2p8mulb_maskz(predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Zero inactive bytes after gf2p8mulb.
constexpr simd< std::uint8_t, 16, Arch > gf2p8mulb_mask(simd< std::uint8_t, 16, Arch > src, predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Merge inactive bytes from src after gf2p8mulb.
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineqb_maskz(predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Zero inactive bytes after gf2p8affineqb.
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineinvqb(simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Invert each field byte, apply its lane's binary matrix, and XOR Imm8.
constexpr simd< std::uint8_t, 16, Arch > gf2p8mulb(simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Multiply corresponding bytes in GF(2^8).
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineqb(simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Apply the binary matrix in each 64-bit lane and XOR Imm8.
constexpr simd< std::uint8_t, 16, Arch > gf2p8affineinvqb_mask(simd< std::uint8_t, 16, Arch > src, predicate< 16, Arch > k, simd< std::uint8_t, 16, Arch > a, simd< std::uint64_t, 2, Arch > matrix) noexcept
Merge inactive bytes from src after gf2p8affineinvqb.
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Standard-library adaptations documented here for SIMD value types.
Omitted architecture arguments use the native.simd provider's baseline.