native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
vnni.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_vnni {
13// Internal register helpers for the native.x86.vnni module.
14
15
16 // 128-bit core operations.
18 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
20 __m128i dpbusd(__m128i accumulator, __m128i a, __m128i b) noexcept {
21 return _mm_dpbusd_avx_epi32(accumulator, a, b);
22 }
23
25 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
26 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
27 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
28 __m128i dpbusd(__m128i accumulator, __m128i a, __m128i b) noexcept {
29 return _mm_dpbusd_epi32(accumulator, a, b);
30 }
31
33 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
34 Arch.has(x86_feature::avx512vl))
35 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
36 __m128i mask_dpbusd(__m128i accumulator, __mmask8 mask, __m128i a, __m128i b) noexcept {
37 return _mm_mask_dpbusd_epi32(accumulator, mask, a, b);
38 }
39
41 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
42 Arch.has(x86_feature::avx512vl))
43 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
44 __m128i maskz_dpbusd(__mmask8 mask, __m128i accumulator, __m128i a, __m128i b) noexcept {
45 return _mm_maskz_dpbusd_epi32(mask, accumulator, a, b);
46 }
47
49 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
51 __m128i dpbusds(__m128i accumulator, __m128i a, __m128i b) noexcept {
52 return _mm_dpbusds_avx_epi32(accumulator, a, b);
53 }
54
56 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
57 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
58 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
59 __m128i dpbusds(__m128i accumulator, __m128i a, __m128i b) noexcept {
60 return _mm_dpbusds_epi32(accumulator, a, b);
61 }
62
64 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
65 Arch.has(x86_feature::avx512vl))
66 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
67 __m128i mask_dpbusds(__m128i accumulator, __mmask8 mask, __m128i a, __m128i b) noexcept {
68 return _mm_mask_dpbusds_epi32(accumulator, mask, a, b);
69 }
70
72 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
73 Arch.has(x86_feature::avx512vl))
74 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
75 __m128i maskz_dpbusds(__mmask8 mask, __m128i accumulator, __m128i a, __m128i b) noexcept {
76 return _mm_maskz_dpbusds_epi32(mask, accumulator, a, b);
77 }
78
80 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
82 __m128i dpwssd(__m128i accumulator, __m128i a, __m128i b) noexcept {
83 return _mm_dpwssd_avx_epi32(accumulator, a, b);
84 }
85
87 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
88 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
89 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
90 __m128i dpwssd(__m128i accumulator, __m128i a, __m128i b) noexcept {
91 return _mm_dpwssd_epi32(accumulator, a, b);
92 }
93
95 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
96 Arch.has(x86_feature::avx512vl))
97 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
98 __m128i mask_dpwssd(__m128i accumulator, __mmask8 mask, __m128i a, __m128i b) noexcept {
99 return _mm_mask_dpwssd_epi32(accumulator, mask, a, b);
100 }
101
103 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
104 Arch.has(x86_feature::avx512vl))
105 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
106 __m128i maskz_dpwssd(__mmask8 mask, __m128i accumulator, __m128i a, __m128i b) noexcept {
107 return _mm_maskz_dpwssd_epi32(mask, accumulator, a, b);
108 }
109
111 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
113 __m128i dpwssds(__m128i accumulator, __m128i a, __m128i b) noexcept {
114 return _mm_dpwssds_avx_epi32(accumulator, a, b);
115 }
116
118 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
119 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
120 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
121 __m128i dpwssds(__m128i accumulator, __m128i a, __m128i b) noexcept {
122 return _mm_dpwssds_epi32(accumulator, a, b);
123 }
124
126 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
127 Arch.has(x86_feature::avx512vl))
128 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
129 __m128i mask_dpwssds(__m128i accumulator, __mmask8 mask, __m128i a, __m128i b) noexcept {
130 return _mm_mask_dpwssds_epi32(accumulator, mask, a, b);
131 }
132
134 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
135 Arch.has(x86_feature::avx512vl))
136 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
137 __m128i maskz_dpwssds(__mmask8 mask, __m128i accumulator, __m128i a, __m128i b) noexcept {
138 return _mm_maskz_dpwssds_epi32(mask, accumulator, a, b);
139 }
140
141 // 256-bit core operations.
143 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
145 __m256i dpbusd(__m256i accumulator, __m256i a, __m256i b) noexcept {
146 return _mm256_dpbusd_avx_epi32(accumulator, a, b);
147 }
148
150 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
151 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
152 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
153 __m256i dpbusd(__m256i accumulator, __m256i a, __m256i b) noexcept {
154 return _mm256_dpbusd_epi32(accumulator, a, b);
155 }
156
158 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
159 Arch.has(x86_feature::avx512vl))
160 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
161 __m256i mask_dpbusd(__m256i accumulator, __mmask8 mask, __m256i a, __m256i b) noexcept {
162 return _mm256_mask_dpbusd_epi32(accumulator, mask, a, b);
163 }
164
166 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
167 Arch.has(x86_feature::avx512vl))
168 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
169 __m256i maskz_dpbusd(__mmask8 mask, __m256i accumulator, __m256i a, __m256i b) noexcept {
170 return _mm256_maskz_dpbusd_epi32(mask, accumulator, a, b);
171 }
172
174 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
176 __m256i dpbusds(__m256i accumulator, __m256i a, __m256i b) noexcept {
177 return _mm256_dpbusds_avx_epi32(accumulator, a, b);
178 }
179
181 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
182 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
183 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
184 __m256i dpbusds(__m256i accumulator, __m256i a, __m256i b) noexcept {
185 return _mm256_dpbusds_epi32(accumulator, a, b);
186 }
187
189 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
190 Arch.has(x86_feature::avx512vl))
191 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
192 __m256i mask_dpbusds(__m256i accumulator, __mmask8 mask, __m256i a, __m256i b) noexcept {
193 return _mm256_mask_dpbusds_epi32(accumulator, mask, a, b);
194 }
195
197 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
198 Arch.has(x86_feature::avx512vl))
199 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
200 __m256i maskz_dpbusds(__mmask8 mask, __m256i accumulator, __m256i a, __m256i b) noexcept {
201 return _mm256_maskz_dpbusds_epi32(mask, accumulator, a, b);
202 }
203
205 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
207 __m256i dpwssd(__m256i accumulator, __m256i a, __m256i b) noexcept {
208 return _mm256_dpwssd_avx_epi32(accumulator, a, b);
209 }
210
212 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
213 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
214 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
215 __m256i dpwssd(__m256i accumulator, __m256i a, __m256i b) noexcept {
216 return _mm256_dpwssd_epi32(accumulator, a, b);
217 }
218
220 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
221 Arch.has(x86_feature::avx512vl))
222 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
223 __m256i mask_dpwssd(__m256i accumulator, __mmask8 mask, __m256i a, __m256i b) noexcept {
224 return _mm256_mask_dpwssd_epi32(accumulator, mask, a, b);
225 }
226
228 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
229 Arch.has(x86_feature::avx512vl))
230 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
231 __m256i maskz_dpwssd(__mmask8 mask, __m256i accumulator, __m256i a, __m256i b) noexcept {
232 return _mm256_maskz_dpwssd_epi32(mask, accumulator, a, b);
233 }
234
236 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
238 __m256i dpwssds(__m256i accumulator, __m256i a, __m256i b) noexcept {
239 return _mm256_dpwssds_avx_epi32(accumulator, a, b);
240 }
241
243 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
244 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
245 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
246 __m256i dpwssds(__m256i accumulator, __m256i a, __m256i b) noexcept {
247 return _mm256_dpwssds_epi32(accumulator, a, b);
248 }
249
251 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
252 Arch.has(x86_feature::avx512vl))
253 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
254 __m256i mask_dpwssds(__m256i accumulator, __mmask8 mask, __m256i a, __m256i b) noexcept {
255 return _mm256_mask_dpwssds_epi32(accumulator, mask, a, b);
256 }
257
259 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
260 Arch.has(x86_feature::avx512vl))
261 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
262 __m256i maskz_dpwssds(__mmask8 mask, __m256i accumulator, __m256i a, __m256i b) noexcept {
263 return _mm256_maskz_dpwssds_epi32(mask, accumulator, a, b);
264 }
265
266 // 512-bit core operations.
268 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
270 __m512i dpbusd(__m512i accumulator, __m512i a, __m512i b) noexcept {
271 return _mm512_dpbusd_epi32(accumulator, a, b);
272 }
273
275 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
277 __m512i mask_dpbusd(__m512i accumulator, __mmask16 mask, __m512i a, __m512i b) noexcept {
278 return _mm512_mask_dpbusd_epi32(accumulator, mask, a, b);
279 }
280
282 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
284 __m512i maskz_dpbusd(__mmask16 mask, __m512i accumulator, __m512i a, __m512i b) noexcept {
285 return _mm512_maskz_dpbusd_epi32(mask, accumulator, a, b);
286 }
287
289 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
291 __m512i dpbusds(__m512i accumulator, __m512i a, __m512i b) noexcept {
292 return _mm512_dpbusds_epi32(accumulator, a, b);
293 }
294
296 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
298 __m512i mask_dpbusds(__m512i accumulator, __mmask16 mask, __m512i a, __m512i b) noexcept {
299 return _mm512_mask_dpbusds_epi32(accumulator, mask, a, b);
300 }
301
303 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
305 __m512i maskz_dpbusds(__mmask16 mask, __m512i accumulator, __m512i a, __m512i b) noexcept {
306 return _mm512_maskz_dpbusds_epi32(mask, accumulator, a, b);
307 }
308
310 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
312 __m512i dpwssd(__m512i accumulator, __m512i a, __m512i b) noexcept {
313 return _mm512_dpwssd_epi32(accumulator, a, b);
314 }
315
317 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
319 __m512i mask_dpwssd(__m512i accumulator, __mmask16 mask, __m512i a, __m512i b) noexcept {
320 return _mm512_mask_dpwssd_epi32(accumulator, mask, a, b);
321 }
322
324 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
326 __m512i maskz_dpwssd(__mmask16 mask, __m512i accumulator, __m512i a, __m512i b) noexcept {
327 return _mm512_maskz_dpwssd_epi32(mask, accumulator, a, b);
328 }
329
331 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
333 __m512i dpwssds(__m512i accumulator, __m512i a, __m512i b) noexcept {
334 return _mm512_dpwssds_epi32(accumulator, a, b);
335 }
336
338 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
340 __m512i mask_dpwssds(__m512i accumulator, __mmask16 mask, __m512i a, __m512i b) noexcept {
341 return _mm512_mask_dpwssds_epi32(accumulator, mask, a, b);
342 }
343
345 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
347 __m512i maskz_dpwssds(__mmask16 mask, __m512i accumulator, __m512i a, __m512i b) noexcept {
348 return _mm512_maskz_dpwssds_epi32(mask, accumulator, a, b);
349 }
350
352 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
354 __m128i dpbssd(__m128i accumulator, __m128i a, __m128i b) noexcept {
355 return _mm_dpbssd_epi32(accumulator, a, b);
356 }
357
359 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
361 __m256i dpbssd(__m256i accumulator, __m256i a, __m256i b) noexcept {
362 return _mm256_dpbssd_epi32(accumulator, a, b);
363 }
364
366 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
368 __m128i dpbssds(__m128i accumulator, __m128i a, __m128i b) noexcept {
369 return _mm_dpbssds_epi32(accumulator, a, b);
370 }
371
373 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
375 __m256i dpbssds(__m256i accumulator, __m256i a, __m256i b) noexcept {
376 return _mm256_dpbssds_epi32(accumulator, a, b);
377 }
378
380 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
382 __m128i dpbsud(__m128i accumulator, __m128i a, __m128i b) noexcept {
383 return _mm_dpbsud_epi32(accumulator, a, b);
384 }
385
387 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
389 __m256i dpbsud(__m256i accumulator, __m256i a, __m256i b) noexcept {
390 return _mm256_dpbsud_epi32(accumulator, a, b);
391 }
392
394 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
396 __m128i dpbsuds(__m128i accumulator, __m128i a, __m128i b) noexcept {
397 return _mm_dpbsuds_epi32(accumulator, a, b);
398 }
399
401 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
403 __m256i dpbsuds(__m256i accumulator, __m256i a, __m256i b) noexcept {
404 return _mm256_dpbsuds_epi32(accumulator, a, b);
405 }
406
408 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
410 __m128i dpbuud(__m128i accumulator, __m128i a, __m128i b) noexcept {
411 return _mm_dpbuud_epi32(accumulator, a, b);
412 }
413
415 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
417 __m256i dpbuud(__m256i accumulator, __m256i a, __m256i b) noexcept {
418 return _mm256_dpbuud_epi32(accumulator, a, b);
419 }
420
422 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
424 __m128i dpbuuds(__m128i accumulator, __m128i a, __m128i b) noexcept {
425 return _mm_dpbuuds_epi32(accumulator, a, b);
426 }
427
429 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
431 __m256i dpbuuds(__m256i accumulator, __m256i a, __m256i b) noexcept {
432 return _mm256_dpbuuds_epi32(accumulator, a, b);
433 }
434
436 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
438 __m128i dpwsud(__m128i accumulator, __m128i a, __m128i b) noexcept {
439 return _mm_dpwsud_epi32(accumulator, a, b);
440 }
441
443 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
445 __m256i dpwsud(__m256i accumulator, __m256i a, __m256i b) noexcept {
446 return _mm256_dpwsud_epi32(accumulator, a, b);
447 }
448
450 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
452 __m128i dpwsuds(__m128i accumulator, __m128i a, __m128i b) noexcept {
453 return _mm_dpwsuds_epi32(accumulator, a, b);
454 }
455
457 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
459 __m256i dpwsuds(__m256i accumulator, __m256i a, __m256i b) noexcept {
460 return _mm256_dpwsuds_epi32(accumulator, a, b);
461 }
462
464 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
466 __m128i dpwusd(__m128i accumulator, __m128i a, __m128i b) noexcept {
467 return _mm_dpwusd_epi32(accumulator, a, b);
468 }
469
471 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
473 __m256i dpwusd(__m256i accumulator, __m256i a, __m256i b) noexcept {
474 return _mm256_dpwusd_epi32(accumulator, a, b);
475 }
476
478 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
480 __m128i dpwusds(__m128i accumulator, __m128i a, __m128i b) noexcept {
481 return _mm_dpwusds_epi32(accumulator, a, b);
482 }
483
485 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
487 __m256i dpwusds(__m256i accumulator, __m256i a, __m256i b) noexcept {
488 return _mm256_dpwusds_epi32(accumulator, a, b);
489 }
490
492 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
494 __m128i dpwuud(__m128i accumulator, __m128i a, __m128i b) noexcept {
495 return _mm_dpwuud_epi32(accumulator, a, b);
496 }
497
499 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
501 __m256i dpwuud(__m256i accumulator, __m256i a, __m256i b) noexcept {
502 return _mm256_dpwuud_epi32(accumulator, a, b);
503 }
504
506 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
508 __m128i dpwuuds(__m128i accumulator, __m128i a, __m128i b) noexcept {
509 return _mm_dpwuuds_epi32(accumulator, a, b);
510 }
511
513 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
515 __m256i dpwuuds(__m256i accumulator, __m256i a, __m256i b) noexcept {
516 return _mm256_dpwuuds_epi32(accumulator, a, b);
517 }
518
519 // Exact vector operands prevent Clang's permissive vector conversions from
520 // selecting an instruction for floating-point or mixed register shapes.
522 namespace detail {
523 template<class S, class A, class B>
524 concept vnni_registers = __is_same(S, A) && __is_same(A, B) &&
525 (__is_same(S, __m128i) || __is_same(S, __m256i) || __is_same(S, __m512i));
526 }
527 template<isa<x86> Arch, class S, class A, class B>
528 void dpbusd(S, A, B) = delete;
529 template<isa<x86> Arch, class S, class A, class B>
530 void dpbusds(S, A, B) = delete;
531 template<isa<x86> Arch, class S, class A, class B>
532 void dpwssd(S, A, B) = delete;
533 template<isa<x86> Arch, class S, class A, class B>
534 void dpwssds(S, A, B) = delete;
535 template<isa<x86> Arch, class S, class A, class B>
536 void dpbssd(S, A, B) = delete;
537 template<isa<x86> Arch, class S, class A, class B>
538 void dpbssds(S, A, B) = delete;
539 template<isa<x86> Arch, class S, class A, class B>
540 void dpbsud(S, A, B) = delete;
541 template<isa<x86> Arch, class S, class A, class B>
542 void dpbsuds(S, A, B) = delete;
543 template<isa<x86> Arch, class S, class A, class B>
544 void dpbuud(S, A, B) = delete;
545 template<isa<x86> Arch, class S, class A, class B>
546 void dpbuuds(S, A, B) = delete;
547 template<isa<x86> Arch, class S, class A, class B>
548 void dpwsud(S, A, B) = delete;
549 template<isa<x86> Arch, class S, class A, class B>
550 void dpwsuds(S, A, B) = delete;
551 template<isa<x86> Arch, class S, class A, class B>
552 void dpwusd(S, A, B) = delete;
553 template<isa<x86> Arch, class S, class A, class B>
554 void dpwusds(S, A, B) = delete;
555 template<isa<x86> Arch, class S, class A, class B>
556 void dpwuud(S, A, B) = delete;
557 template<isa<x86> Arch, class S, class A, class B>
558 void dpwuuds(S, A, B) = delete;
559 template<isa<x86> Arch, class S, class M, class A, class B>
560 requires(!detail::vnni_registers<S, A, B>)
561 void mask_dpbusd(S, M, A, B) = delete;
562 template<isa<x86> Arch, class S, class M, class A, class B>
563 requires(!detail::vnni_registers<S, A, B>)
564 void maskz_dpbusd(M, S, A, B) = delete;
565 template<isa<x86> Arch, class S, class M, class A, class B>
566 requires(!detail::vnni_registers<S, A, B>)
567 void mask_dpbusds(S, M, A, B) = delete;
568 template<isa<x86> Arch, class S, class M, class A, class B>
569 requires(!detail::vnni_registers<S, A, B>)
570 void maskz_dpbusds(M, S, A, B) = delete;
571 template<isa<x86> Arch, class S, class M, class A, class B>
572 requires(!detail::vnni_registers<S, A, B>)
573 void mask_dpwssd(S, M, A, B) = delete;
574 template<isa<x86> Arch, class S, class M, class A, class B>
575 requires(!detail::vnni_registers<S, A, B>)
576 void maskz_dpwssd(M, S, A, B) = delete;
577 template<isa<x86> Arch, class S, class M, class A, class B>
578 requires(!detail::vnni_registers<S, A, B>)
579 void mask_dpwssds(S, M, A, B) = delete;
580 template<isa<x86> Arch, class S, class M, class A, class B>
581 requires(!detail::vnni_registers<S, A, B>)
582 void maskz_dpwssds(M, S, A, B) = delete;
584
585}
586#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
typename mask_traits< std::remove_cvref_t< T > >::type mask
Definition mask_traits.h:22