3#include "native/config.h"
9#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
10namespace native::detail::x86_avx512cd {
13 template<isa<x86> Arch>
14 requires(Arch.has(x86_feature::avx512f) &&
15 Arch.has(x86_feature::avx512cd) &&
16 Arch.has(x86_feature::avx512vl))
18 __m128i vpconflictd(__m128i value) noexcept {
19 return _mm_conflict_epi32(value);
22 template<isa<x86> Arch>
23 requires(Arch.has(x86_feature::avx512f) &&
24 Arch.has(x86_feature::avx512cd) &&
25 Arch.has(x86_feature::avx512vl))
27 __m128i mask_vpconflictd(__m128i source, __mmask8
mask, __m128i value) noexcept {
28 return _mm_mask_conflict_epi32(source,
mask, value);
31 template<isa<x86> Arch>
32 requires(Arch.has(x86_feature::avx512f) &&
33 Arch.has(x86_feature::avx512cd) &&
34 Arch.has(x86_feature::avx512vl))
36 __m128i maskz_vpconflictd(__mmask8
mask, __m128i value) noexcept {
37 return _mm_maskz_conflict_epi32(
mask, value);
40 template<isa<x86> Arch>
41 requires(Arch.has(x86_feature::avx512f) &&
42 Arch.has(x86_feature::avx512cd) &&
43 Arch.has(x86_feature::avx512vl))
45 __m128i vplzcntd(__m128i value) noexcept {
46 return _mm_lzcnt_epi32(value);
49 template<isa<x86> Arch>
50 requires(Arch.has(x86_feature::avx512f) &&
51 Arch.has(x86_feature::avx512cd) &&
52 Arch.has(x86_feature::avx512vl))
54 __m128i mask_vplzcntd(__m128i source, __mmask8
mask, __m128i value) noexcept {
55 return _mm_mask_lzcnt_epi32(source,
mask, value);
58 template<isa<x86> Arch>
59 requires(Arch.has(x86_feature::avx512f) &&
60 Arch.has(x86_feature::avx512cd) &&
61 Arch.has(x86_feature::avx512vl))
63 __m128i maskz_vplzcntd(__mmask8
mask, __m128i value) noexcept {
64 return _mm_maskz_lzcnt_epi32(
mask, value);
67 template<isa<x86> Arch>
68 requires(Arch.has(x86_feature::avx512f) &&
69 Arch.has(x86_feature::avx512cd) &&
70 Arch.has(x86_feature::avx512vl))
72 __m128i vpconflictq(__m128i value) noexcept {
73 return _mm_conflict_epi64(value);
76 template<isa<x86> Arch>
77 requires(Arch.has(x86_feature::avx512f) &&
78 Arch.has(x86_feature::avx512cd) &&
79 Arch.has(x86_feature::avx512vl))
81 __m128i mask_vpconflictq(__m128i source, __mmask8
mask, __m128i value) noexcept {
82 return _mm_mask_conflict_epi64(source,
mask, value);
85 template<isa<x86> Arch>
86 requires(Arch.has(x86_feature::avx512f) &&
87 Arch.has(x86_feature::avx512cd) &&
88 Arch.has(x86_feature::avx512vl))
90 __m128i maskz_vpconflictq(__mmask8
mask, __m128i value) noexcept {
91 return _mm_maskz_conflict_epi64(
mask, value);
94 template<isa<x86> Arch>
95 requires(Arch.has(x86_feature::avx512f) &&
96 Arch.has(x86_feature::avx512cd) &&
97 Arch.has(x86_feature::avx512vl))
99 __m128i vplzcntq(__m128i value) noexcept {
100 return _mm_lzcnt_epi64(value);
103 template<isa<x86> Arch>
104 requires(Arch.has(x86_feature::avx512f) &&
105 Arch.has(x86_feature::avx512cd) &&
106 Arch.has(x86_feature::avx512vl))
108 __m128i mask_vplzcntq(__m128i source, __mmask8
mask, __m128i value) noexcept {
109 return _mm_mask_lzcnt_epi64(source,
mask, value);
112 template<isa<x86> Arch>
113 requires(Arch.has(x86_feature::avx512f) &&
114 Arch.has(x86_feature::avx512cd) &&
115 Arch.has(x86_feature::avx512vl))
117 __m128i maskz_vplzcntq(__mmask8
mask, __m128i value) noexcept {
118 return _mm_maskz_lzcnt_epi64(
mask, value);
121 template<isa<x86> Arch>
122 requires(Arch.has(x86_feature::avx512f) &&
123 Arch.has(x86_feature::avx512cd) &&
124 Arch.has(x86_feature::avx512vl))
126 __m256i vpconflictd(__m256i value) noexcept {
127 return _mm256_conflict_epi32(value);
130 template<isa<x86> Arch>
131 requires(Arch.has(x86_feature::avx512f) &&
132 Arch.has(x86_feature::avx512cd) &&
133 Arch.has(x86_feature::avx512vl))
135 __m256i mask_vpconflictd(__m256i source, __mmask8
mask, __m256i value) noexcept {
136 return _mm256_mask_conflict_epi32(source,
mask, value);
139 template<isa<x86> Arch>
140 requires(Arch.has(x86_feature::avx512f) &&
141 Arch.has(x86_feature::avx512cd) &&
142 Arch.has(x86_feature::avx512vl))
144 __m256i maskz_vpconflictd(__mmask8
mask, __m256i value) noexcept {
145 return _mm256_maskz_conflict_epi32(
mask, value);
148 template<isa<x86> Arch>
149 requires(Arch.has(x86_feature::avx512f) &&
150 Arch.has(x86_feature::avx512cd) &&
151 Arch.has(x86_feature::avx512vl))
153 __m256i vplzcntd(__m256i value) noexcept {
154 return _mm256_lzcnt_epi32(value);
157 template<isa<x86> Arch>
158 requires(Arch.has(x86_feature::avx512f) &&
159 Arch.has(x86_feature::avx512cd) &&
160 Arch.has(x86_feature::avx512vl))
162 __m256i mask_vplzcntd(__m256i source, __mmask8
mask, __m256i value) noexcept {
163 return _mm256_mask_lzcnt_epi32(source,
mask, value);
166 template<isa<x86> Arch>
167 requires(Arch.has(x86_feature::avx512f) &&
168 Arch.has(x86_feature::avx512cd) &&
169 Arch.has(x86_feature::avx512vl))
171 __m256i maskz_vplzcntd(__mmask8
mask, __m256i value) noexcept {
172 return _mm256_maskz_lzcnt_epi32(
mask, value);
175 template<isa<x86> Arch>
176 requires(Arch.has(x86_feature::avx512f) &&
177 Arch.has(x86_feature::avx512cd) &&
178 Arch.has(x86_feature::avx512vl))
180 __m256i vpconflictq(__m256i value) noexcept {
181 return _mm256_conflict_epi64(value);
184 template<isa<x86> Arch>
185 requires(Arch.has(x86_feature::avx512f) &&
186 Arch.has(x86_feature::avx512cd) &&
187 Arch.has(x86_feature::avx512vl))
189 __m256i mask_vpconflictq(__m256i source, __mmask8
mask, __m256i value) noexcept {
190 return _mm256_mask_conflict_epi64(source,
mask, value);
193 template<isa<x86> Arch>
194 requires(Arch.has(x86_feature::avx512f) &&
195 Arch.has(x86_feature::avx512cd) &&
196 Arch.has(x86_feature::avx512vl))
198 __m256i maskz_vpconflictq(__mmask8
mask, __m256i value) noexcept {
199 return _mm256_maskz_conflict_epi64(
mask, value);
202 template<isa<x86> Arch>
203 requires(Arch.has(x86_feature::avx512f) &&
204 Arch.has(x86_feature::avx512cd) &&
205 Arch.has(x86_feature::avx512vl))
207 __m256i vplzcntq(__m256i value) noexcept {
208 return _mm256_lzcnt_epi64(value);
211 template<isa<x86> Arch>
212 requires(Arch.has(x86_feature::avx512f) &&
213 Arch.has(x86_feature::avx512cd) &&
214 Arch.has(x86_feature::avx512vl))
216 __m256i mask_vplzcntq(__m256i source, __mmask8
mask, __m256i value) noexcept {
217 return _mm256_mask_lzcnt_epi64(source,
mask, value);
220 template<isa<x86> Arch>
221 requires(Arch.has(x86_feature::avx512f) &&
222 Arch.has(x86_feature::avx512cd) &&
223 Arch.has(x86_feature::avx512vl))
225 __m256i maskz_vplzcntq(__mmask8
mask, __m256i value) noexcept {
226 return _mm256_maskz_lzcnt_epi64(
mask, value);
229 template<isa<x86> Arch>
230 requires(Arch.has(x86_feature::avx512f) &&
231 Arch.has(x86_feature::avx512cd))
233 __m512i vpconflictd(__m512i value) noexcept {
234 return _mm512_conflict_epi32(value);
237 template<isa<x86> Arch>
238 requires(Arch.has(x86_feature::avx512f) &&
239 Arch.has(x86_feature::avx512cd))
241 __m512i mask_vpconflictd(__m512i source, __mmask16
mask, __m512i value) noexcept {
242 return _mm512_mask_conflict_epi32(source,
mask, value);
245 template<isa<x86> Arch>
246 requires(Arch.has(x86_feature::avx512f) &&
247 Arch.has(x86_feature::avx512cd))
249 __m512i maskz_vpconflictd(__mmask16
mask, __m512i value) noexcept {
250 return _mm512_maskz_conflict_epi32(
mask, value);
253 template<isa<x86> Arch>
254 requires(Arch.has(x86_feature::avx512f) &&
255 Arch.has(x86_feature::avx512cd))
257 __m512i vplzcntd(__m512i value) noexcept {
258 return _mm512_lzcnt_epi32(value);
261 template<isa<x86> Arch>
262 requires(Arch.has(x86_feature::avx512f) &&
263 Arch.has(x86_feature::avx512cd))
265 __m512i mask_vplzcntd(__m512i source, __mmask16
mask, __m512i value) noexcept {
266 return _mm512_mask_lzcnt_epi32(source,
mask, value);
269 template<isa<x86> Arch>
270 requires(Arch.has(x86_feature::avx512f) &&
271 Arch.has(x86_feature::avx512cd))
273 __m512i maskz_vplzcntd(__mmask16
mask, __m512i value) noexcept {
274 return _mm512_maskz_lzcnt_epi32(
mask, value);
277 template<isa<x86> Arch>
278 requires(Arch.has(x86_feature::avx512f) &&
279 Arch.has(x86_feature::avx512cd))
281 __m512i vpconflictq(__m512i value) noexcept {
282 return _mm512_conflict_epi64(value);
285 template<isa<x86> Arch>
286 requires(Arch.has(x86_feature::avx512f) &&
287 Arch.has(x86_feature::avx512cd))
289 __m512i mask_vpconflictq(__m512i source, __mmask8
mask, __m512i value) noexcept {
290 return _mm512_mask_conflict_epi64(source,
mask, value);
293 template<isa<x86> Arch>
294 requires(Arch.has(x86_feature::avx512f) &&
295 Arch.has(x86_feature::avx512cd))
297 __m512i maskz_vpconflictq(__mmask8
mask, __m512i value) noexcept {
298 return _mm512_maskz_conflict_epi64(
mask, value);
301 template<isa<x86> Arch>
302 requires(Arch.has(x86_feature::avx512f) &&
303 Arch.has(x86_feature::avx512cd))
305 __m512i vplzcntq(__m512i value) noexcept {
306 return _mm512_lzcnt_epi64(value);
309 template<isa<x86> Arch>
310 requires(Arch.has(x86_feature::avx512f) &&
311 Arch.has(x86_feature::avx512cd))
313 __m512i mask_vplzcntq(__m512i source, __mmask8
mask, __m512i value) noexcept {
314 return _mm512_mask_lzcnt_epi64(source,
mask, value);
317 template<isa<x86> Arch>
318 requires(Arch.has(x86_feature::avx512f) &&
319 Arch.has(x86_feature::avx512cd))
321 __m512i maskz_vplzcntq(__mmask8
mask, __m512i value) noexcept {
322 return _mm512_maskz_lzcnt_epi64(
mask, value);
332namespace native::detail::x86_avx512cd_constant {
334 template<
bool Conflict,
class V>
335 constexpr V evaluate(V value, V source, std::uint64_t
mask)
noexcept {
336 using value_type =
typename V::value_type;
337 std::array<value_type, V::lanes> input{};
338 std::array<value_type, V::lanes> result{};
339 value.store(input.data());
340 source.store(result.data());
341 for (std::size_t lane = 0; lane < V::lanes; ++lane) {
342 if (!((
mask >> lane) & 1)) {
345 if constexpr (Conflict) {
346 value_type matches = 0;
348 for (std::size_t earlier = 0; earlier < lane; ++earlier) {
349 if (input[earlier] == input[lane]) {
350 matches |= value_type{1} << earlier;
353 result[lane] = matches;
355 result[lane] =
static_cast<value_type
>(std::countl_zero(input[lane]));
358 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.
typename mask_traits< std::remove_cvref_t< T > >::type mask