native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.x86.ifma.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3
4#include "native/isa_import.h"
5#include "native/x86/ifma.h"
6
7export module native.x86.ifma;
8export import native.x86.features;
9export import native.simd;
10
11// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
12
13#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
14export namespace native {
23
25 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx))
27 constexpr simd<std::uint64_t, 2, Arch> madd52lo(
28 simd<std::uint64_t, 2, Arch> accumulator, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
29 if consteval {
30 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
31 } else {
33 detail::x86_ifma::madd52lo<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
34 }
35 }
36
38 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) &&
39 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
40 Arch.has(x86_feature::avx512vl))
41 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
44 if consteval {
45 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
46 } else {
48 detail::x86_ifma::madd52lo<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
49 }
50 }
51
53 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) || (Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
54 Arch.has(x86_feature::avx512vl))) &&
55 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
58 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
59 }
60
62 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx))
66 if consteval {
67 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
68 } else {
70 detail::x86_ifma::madd52lo<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
71 }
72 }
73
75 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) &&
76 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
77 Arch.has(x86_feature::avx512vl))
78 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
81 if consteval {
82 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
83 } else {
85 detail::x86_ifma::madd52lo<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
86 }
87 }
88
90 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) || (Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
91 Arch.has(x86_feature::avx512vl))) &&
92 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
95 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
96 }
97
99 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
103 if consteval {
104 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
105 } else {
107 detail::x86_ifma::madd52lo<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
108 }
109 }
110
112 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
113 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
116 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, ~std::uint64_t{0}, false);
117 }
118
120 template<isa<x86> Arch, class... Args>
121 void madd52lo(Args...) = delete;
122
124 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
125 Arch.has(x86_feature::avx512vl))
126 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
127 constexpr simd<std::uint64_t, 2, Arch> mask_madd52lo(
128 simd<std::uint64_t, 2, Arch> accumulator, predicate<2, Arch> mask, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
129 if consteval {
130 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
131 } else {
133 detail::x86_ifma::mask_madd52lo<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
134 }
135 }
136
138 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
139 Arch.has(x86_feature::avx512vl)) &&
140 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
143 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
144 }
145
147 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
148 Arch.has(x86_feature::avx512vl))
149 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
152 if consteval {
153 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
154 } else {
156 detail::x86_ifma::mask_madd52lo<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
157 }
158 }
159
161 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
162 Arch.has(x86_feature::avx512vl)) &&
163 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
166 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
167 }
168
170 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
174 if consteval {
175 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
176 } else {
178 detail::x86_ifma::mask_madd52lo<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
179 }
180 }
181
183 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
184 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
187 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), false);
188 }
189
191 template<isa<x86> Arch, class... Args>
192 void mask_madd52lo(Args...) = delete;
193
195 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
196 Arch.has(x86_feature::avx512vl))
197 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
198 constexpr simd<std::uint64_t, 2, Arch> maskz_madd52lo(
199 predicate<2, Arch> mask, simd<std::uint64_t, 2, Arch> accumulator, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
200 if consteval {
201 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
202 } else {
204 detail::x86_ifma::maskz_madd52lo<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
205 }
206 }
207
209 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
210 Arch.has(x86_feature::avx512vl)) &&
211 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
214 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
215 }
216
218 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
219 Arch.has(x86_feature::avx512vl))
220 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
223 if consteval {
224 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
225 } else {
227 detail::x86_ifma::maskz_madd52lo<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
228 }
229 }
230
232 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
233 Arch.has(x86_feature::avx512vl)) &&
234 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
237 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
238 }
239
241 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
245 if consteval {
246 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
247 } else {
249 detail::x86_ifma::maskz_madd52lo<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
250 }
251 }
252
254 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
255 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
258 return detail::x86_ifma_constant::accumulate<false>(accumulator, a, b, mask.to_bitset(), true);
259 }
260
262 template<isa<x86> Arch, class... Args>
263 void maskz_madd52lo(Args...) = delete;
264
266 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx))
268 constexpr simd<std::uint64_t, 2, Arch> madd52hi(
269 simd<std::uint64_t, 2, Arch> accumulator, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
270 if consteval {
271 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
272 } else {
274 detail::x86_ifma::madd52hi<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
275 }
276 }
277
279 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) &&
280 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
281 Arch.has(x86_feature::avx512vl))
282 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
285 if consteval {
286 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
287 } else {
289 detail::x86_ifma::madd52hi<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
290 }
291 }
292
294 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) || (Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
295 Arch.has(x86_feature::avx512vl))) &&
296 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
299 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
300 }
301
303 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx))
307 if consteval {
308 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
309 } else {
311 detail::x86_ifma::madd52hi<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
312 }
313 }
314
316 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) &&
317 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
318 Arch.has(x86_feature::avx512vl))
319 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
322 if consteval {
323 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
324 } else {
326 detail::x86_ifma::madd52hi<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
327 }
328 }
329
331 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxifma) && Arch.has(x86_feature::avx)) || (Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
332 Arch.has(x86_feature::avx512vl))) &&
333 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
336 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
337 }
338
340 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
344 if consteval {
345 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
346 } else {
348 detail::x86_ifma::madd52hi<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
349 }
350 }
351
353 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
354 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
357 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, ~std::uint64_t{0}, false);
358 }
359
361 template<isa<x86> Arch, class... Args>
362 void madd52hi(Args...) = delete;
363
365 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
366 Arch.has(x86_feature::avx512vl))
367 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
368 constexpr simd<std::uint64_t, 2, Arch> mask_madd52hi(
369 simd<std::uint64_t, 2, Arch> accumulator, predicate<2, Arch> mask, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
370 if consteval {
371 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
372 } else {
374 detail::x86_ifma::mask_madd52hi<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
375 }
376 }
377
379 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
380 Arch.has(x86_feature::avx512vl)) &&
381 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
384 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
385 }
386
388 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
389 Arch.has(x86_feature::avx512vl))
390 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
393 if consteval {
394 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
395 } else {
397 detail::x86_ifma::mask_madd52hi<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
398 }
399 }
400
402 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
403 Arch.has(x86_feature::avx512vl)) &&
404 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
407 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
408 }
409
411 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
415 if consteval {
416 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
417 } else {
419 detail::x86_ifma::mask_madd52hi<Arch>(accumulator.to_native(), static_cast<__mmask8>(mask.to_bitset()), a.to_native(), b.to_native()));
420 }
421 }
422
424 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
425 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
428 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), false);
429 }
430
432 template<isa<x86> Arch, class... Args>
433 void mask_madd52hi(Args...) = delete;
434
436 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
437 Arch.has(x86_feature::avx512vl))
438 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
439 constexpr simd<std::uint64_t, 2, Arch> maskz_madd52hi(
440 predicate<2, Arch> mask, simd<std::uint64_t, 2, Arch> accumulator, simd<std::uint64_t, 2, Arch> a, simd<std::uint64_t, 2, Arch> b) noexcept {
441 if consteval {
442 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
443 } else {
445 detail::x86_ifma::maskz_madd52hi<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
446 }
447 }
448
450 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
451 Arch.has(x86_feature::avx512vl)) &&
452 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
455 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
456 }
457
459 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
460 Arch.has(x86_feature::avx512vl))
461 native_nodiscard native_inline native_const native_target("avx512f,avx512ifma,avx512vl")
464 if consteval {
465 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
466 } else {
468 detail::x86_ifma::maskz_madd52hi<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
469 }
470 }
471
473 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma) &&
474 Arch.has(x86_feature::avx512vl)) &&
475 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
478 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
479 }
480
482 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma))
486 if consteval {
487 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
488 } else {
490 detail::x86_ifma::maskz_madd52hi<Arch>(static_cast<__mmask8>(mask.to_bitset()), accumulator.to_native(), a.to_native(), b.to_native()));
491 }
492 }
493
495 template<isa<x86> Arch> requires(!(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512ifma)) &&
496 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
499 return detail::x86_ifma_constant::accumulate<true>(accumulator, a, b, mask.to_bitset(), true);
500 }
501
503 template<isa<x86> Arch, class... Args>
504 void maskz_madd52hi(Args...) = delete;
505
507}
508#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
typename mask_traits< std::remove_cvref_t< T > >::type mask
Definition mask_traits.h:22
constexpr simd< std::uint64_t, 2, Arch > mask_madd52lo(simd< std::uint64_t, 2, Arch > accumulator, predicate< 2, Arch > mask, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate low 52-bit products in 2 lanes; inactive lanes retain the accumulator.
constexpr simd< std::uint64_t, 2, Arch > maskz_madd52lo(predicate< 2, Arch > mask, simd< std::uint64_t, 2, Arch > accumulator, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate low 52-bit products in 2 lanes; inactive lanes become zero.
constexpr simd< std::uint64_t, 2, Arch > maskz_madd52hi(predicate< 2, Arch > mask, simd< std::uint64_t, 2, Arch > accumulator, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate high 52-bit products in 2 lanes; inactive lanes become zero.
constexpr simd< std::uint64_t, 2, Arch > madd52hi(simd< std::uint64_t, 2, Arch > accumulator, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate high 52-bit products in 2 lanes; unmasked.
constexpr simd< std::uint64_t, 2, Arch > mask_madd52hi(simd< std::uint64_t, 2, Arch > accumulator, predicate< 2, Arch > mask, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate high 52-bit products in 2 lanes; inactive lanes retain the accumulator.
constexpr simd< std::uint64_t, 2, Arch > madd52lo(simd< std::uint64_t, 2, Arch > accumulator, simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b) noexcept
Accumulate low 52-bit products in 2 lanes; unmasked.
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.