native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
gfni.h
1// SPDX-FileCopyrightText: 2026 Edward Kmett <ekmett@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
3#pragma once
4#include "native/config.h"
5#include "native/attributes.h"
6#include "native/isa.h"
7#if NATIVE_HOST_X86
8#include <immintrin.h>
9#endif
10
11#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
12namespace native::detail::x86_gfni {
13// Internal register helpers for the native.x86.gfni module.
14
15
16 // 128-bit registers.
18 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni))
20 __m128i gf2p8mulb(__m128i a, __m128i b) noexcept {
21 return _mm_gf2p8mul_epi8(a, b);
22 }
23
25 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Imm8 <= 255)
27 __m128i gf2p8affineqb(__m128i a, __m128i matrix) noexcept {
28 return _mm_gf2p8affine_epi64_epi8(a, matrix, Imm8);
29 }
30
32 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Imm8 <= 255)
34 __m128i gf2p8affineinvqb(__m128i a, __m128i matrix) noexcept {
35 return _mm_gf2p8affineinv_epi64_epi8(a, matrix, Imm8);
36 }
37
39 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
40 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
42 __m128i gf2p8mulb_mask(__m128i src, __mmask16 k, __m128i a, __m128i b) noexcept {
43 return _mm_mask_gf2p8mul_epi8(src, k, a, b);
44 }
45
47 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
48 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
50 __m128i gf2p8mulb_maskz(__mmask16 k, __m128i a, __m128i b) noexcept {
51 return _mm_maskz_gf2p8mul_epi8(k, a, b);
52 }
53
55 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
56 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
58 __m128i gf2p8affineqb_mask(__m128i src, __mmask16 k, __m128i a, __m128i matrix) noexcept {
59 return _mm_mask_gf2p8affine_epi64_epi8(src, k, a, matrix, Imm8);
60 }
61
63 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
64 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
66 __m128i gf2p8affineqb_maskz(__mmask16 k, __m128i a, __m128i matrix) noexcept {
67 return _mm_maskz_gf2p8affine_epi64_epi8(k, a, matrix, Imm8);
68 }
69
71 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
72 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
74 __m128i gf2p8affineinvqb_mask(__m128i src, __mmask16 k, __m128i a, __m128i matrix) noexcept {
75 return _mm_mask_gf2p8affineinv_epi64_epi8(src, k, a, matrix, Imm8);
76 }
77
79 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
80 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
82 __m128i gf2p8affineinvqb_maskz(__mmask16 k, __m128i a, __m128i matrix) noexcept {
83 return _mm_maskz_gf2p8affineinv_epi64_epi8(k, a, matrix, Imm8);
84 }
85
86
87 // 256-bit registers.
89 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx))
91 __m256i gf2p8mulb(__m256i a, __m256i b) noexcept {
92 return _mm256_gf2p8mul_epi8(a, b);
93 }
94
96 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx) && Imm8 <= 255)
98 __m256i gf2p8affineqb(__m256i a, __m256i matrix) noexcept {
99 return _mm256_gf2p8affine_epi64_epi8(a, matrix, Imm8);
100 }
101
103 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx) && Imm8 <= 255)
105 __m256i gf2p8affineinvqb(__m256i a, __m256i matrix) noexcept {
106 return _mm256_gf2p8affineinv_epi64_epi8(a, matrix, Imm8);
107 }
108
110 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
111 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
113 __m256i gf2p8mulb_mask(__m256i src, __mmask32 k, __m256i a, __m256i b) noexcept {
114 return _mm256_mask_gf2p8mul_epi8(src, k, a, b);
115 }
116
118 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
119 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl))
121 __m256i gf2p8mulb_maskz(__mmask32 k, __m256i a, __m256i b) noexcept {
122 return _mm256_maskz_gf2p8mul_epi8(k, a, b);
123 }
124
126 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
127 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
129 __m256i gf2p8affineqb_mask(__m256i src, __mmask32 k, __m256i a, __m256i matrix) noexcept {
130 return _mm256_mask_gf2p8affine_epi64_epi8(src, k, a, matrix, Imm8);
131 }
132
134 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
135 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
137 __m256i gf2p8affineqb_maskz(__mmask32 k, __m256i a, __m256i matrix) noexcept {
138 return _mm256_maskz_gf2p8affine_epi64_epi8(k, a, matrix, Imm8);
139 }
140
142 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
143 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
145 __m256i gf2p8affineinvqb_mask(__m256i src, __mmask32 k, __m256i a, __m256i matrix) noexcept {
146 return _mm256_mask_gf2p8affineinv_epi64_epi8(src, k, a, matrix, Imm8);
147 }
148
150 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
151 Arch.has(x86_feature::avx512bw) && Arch.has(x86_feature::avx512vl) && Imm8 <= 255)
153 __m256i gf2p8affineinvqb_maskz(__mmask32 k, __m256i a, __m256i matrix) noexcept {
154 return _mm256_maskz_gf2p8affineinv_epi64_epi8(k, a, matrix, Imm8);
155 }
156
157
158 // 512-bit registers.
160 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f))
162 __m512i gf2p8mulb(__m512i a, __m512i b) noexcept {
163 return _mm512_gf2p8mul_epi8(a, b);
164 }
165
167 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) && Imm8 <= 255)
169 __m512i gf2p8affineqb(__m512i a, __m512i matrix) noexcept {
170 return _mm512_gf2p8affine_epi64_epi8(a, matrix, Imm8);
171 }
172
174 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) && Imm8 <= 255)
176 __m512i gf2p8affineinvqb(__m512i a, __m512i matrix) noexcept {
177 return _mm512_gf2p8affineinv_epi64_epi8(a, matrix, Imm8);
178 }
179
181 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
182 Arch.has(x86_feature::avx512bw))
184 __m512i gf2p8mulb_mask(__m512i src, __mmask64 k, __m512i a, __m512i b) noexcept {
185 return _mm512_mask_gf2p8mul_epi8(src, k, a, b);
186 }
187
189 template<isa<x86> Arch> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
190 Arch.has(x86_feature::avx512bw))
192 __m512i gf2p8mulb_maskz(__mmask64 k, __m512i a, __m512i b) noexcept {
193 return _mm512_maskz_gf2p8mul_epi8(k, a, b);
194 }
195
197 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
198 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
200 __m512i gf2p8affineqb_mask(__m512i src, __mmask64 k, __m512i a, __m512i matrix) noexcept {
201 return _mm512_mask_gf2p8affine_epi64_epi8(src, k, a, matrix, Imm8);
202 }
203
205 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
206 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
208 __m512i gf2p8affineqb_maskz(__mmask64 k, __m512i a, __m512i matrix) noexcept {
209 return _mm512_maskz_gf2p8affine_epi64_epi8(k, a, matrix, Imm8);
210 }
211
213 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
214 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
216 __m512i gf2p8affineinvqb_mask(__m512i src, __mmask64 k, __m512i a, __m512i matrix) noexcept {
217 return _mm512_mask_gf2p8affineinv_epi64_epi8(src, k, a, matrix, Imm8);
218 }
219
221 template<isa<x86> Arch, unsigned Imm8> requires(Arch.has(x86_feature::gfni) && Arch.has(x86_feature::avx512f) &&
222 Arch.has(x86_feature::avx512bw) && Imm8 <= 255)
224 __m512i gf2p8affineinvqb_maskz(__mmask64 k, __m512i a, __m512i matrix) noexcept {
225 return _mm512_maskz_gf2p8affineinv_epi64_epi8(k, a, matrix, Imm8);
226 }
227
228
229}
230#endif
Compiler attributes for host code, with shader-safe shared modifiers.
#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