native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.wasm.relaxed.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3
4#include "native/isa_import.h"
5#include "native/wasm/relaxed.h"
6
7export module native.wasm.relaxed;
8export import native.wasm.features;
9export import native.simd;
10// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
11#if NATIVE_HOST_WASM || defined(NATIVE_DOXYGEN)
12export namespace native {
19
21 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
23 constexpr simd<std::uint8_t, 16, Arch> i8x16_relaxed_swizzle(simd<std::uint8_t, 16, Arch> a, simd<std::uint8_t, 16, Arch> b) noexcept {
24 if consteval {
25 return detail::wasm_relaxed_constant::swizzle(a, b);
26 } else {
28 detail::wasm_relaxed::i8x16_relaxed_swizzle<Arch>(a.to_native(), b.to_native()));
29 }
30 }
31
33 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
34 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
36 return detail::wasm_relaxed_constant::swizzle(a, b);
37 }
38
40 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
42 constexpr simd<std::int32_t, 4, Arch> i32x4_relaxed_trunc_f32x4(simd<float, 4, Arch> a) noexcept {
43 if consteval {
44 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
45 } else {
47 detail::wasm_relaxed::i32x4_relaxed_trunc_f32x4<Arch>(a.to_native()));
48 }
49 }
50
52 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
53 requires { sizeof(simd<std::int32_t, 4, Arch>); })
55 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
56 }
57
59 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
61 constexpr simd<std::uint32_t, 4, Arch> u32x4_relaxed_trunc_f32x4(simd<float, 4, Arch> a) noexcept {
62 if consteval {
63 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
64 } else {
66 detail::wasm_relaxed::u32x4_relaxed_trunc_f32x4<Arch>(a.to_native()));
67 }
68 }
69
71 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
72 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
74 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
75 }
76
78 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
80 constexpr simd<std::int32_t, 4, Arch> i32x4_relaxed_trunc_f64x2_zero(simd<double, 2, Arch> a) noexcept {
81 if consteval {
82 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
83 } else {
85 detail::wasm_relaxed::i32x4_relaxed_trunc_f64x2_zero<Arch>(a.to_native()));
86 }
87 }
88
90 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
91 requires { sizeof(simd<std::int32_t, 4, Arch>); })
93 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
94 }
95
97 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
99 constexpr simd<std::uint32_t, 4, Arch> u32x4_relaxed_trunc_f64x2_zero(simd<double, 2, Arch> a) noexcept {
100 if consteval {
101 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
102 } else {
104 detail::wasm_relaxed::u32x4_relaxed_trunc_f64x2_zero<Arch>(a.to_native()));
105 }
106 }
107
109 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
110 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
112 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
113 }
114
116 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
118 constexpr simd<float, 4, Arch> f32x4_relaxed_madd(simd<float, 4, Arch> a, simd<float, 4, Arch> b, simd<float, 4, Arch> c) noexcept {
119 if consteval {
120 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
121 } else {
123 detail::wasm_relaxed::f32x4_relaxed_madd<Arch>(a.to_native(), b.to_native(), c.to_native()));
124 }
125 }
126
128 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
129 requires { sizeof(simd<float, 4, Arch>); })
131 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
132 }
133
135 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
137 constexpr simd<float, 4, Arch> f32x4_relaxed_nmadd(simd<float, 4, Arch> a, simd<float, 4, Arch> b, simd<float, 4, Arch> c) noexcept {
138 if consteval {
139 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
140 } else {
142 detail::wasm_relaxed::f32x4_relaxed_nmadd<Arch>(a.to_native(), b.to_native(), c.to_native()));
143 }
144 }
145
147 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
148 requires { sizeof(simd<float, 4, Arch>); })
150 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
151 }
152
154 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
156 constexpr simd<double, 2, Arch> f64x2_relaxed_madd(simd<double, 2, Arch> a, simd<double, 2, Arch> b, simd<double, 2, Arch> c) noexcept {
157 if consteval {
158 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
159 } else {
161 detail::wasm_relaxed::f64x2_relaxed_madd<Arch>(a.to_native(), b.to_native(), c.to_native()));
162 }
163 }
164
166 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
167 requires { sizeof(simd<double, 2, Arch>); })
169 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
170 }
171
173 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
175 constexpr simd<double, 2, Arch> f64x2_relaxed_nmadd(simd<double, 2, Arch> a, simd<double, 2, Arch> b, simd<double, 2, Arch> c) noexcept {
176 if consteval {
177 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
178 } else {
180 detail::wasm_relaxed::f64x2_relaxed_nmadd<Arch>(a.to_native(), b.to_native(), c.to_native()));
181 }
182 }
183
185 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
186 requires { sizeof(simd<double, 2, Arch>); })
188 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
189 }
190
192 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
194 constexpr simd<std::uint8_t, 16, Arch> i8x16_relaxed_laneselect(
195 simd<std::uint8_t, 16, Arch> a,
196 simd<std::uint8_t, 16, Arch> b,
197 simd<std::uint8_t, 16, Arch> c) noexcept {
198 if consteval {
199 return detail::wasm_relaxed_constant::lane_select(a, b, c);
200 } else {
202 detail::wasm_relaxed::i8x16_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
203 }
204 }
205
207 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
208 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
212 simd<std::uint8_t, 16, Arch> c) noexcept {
213 return detail::wasm_relaxed_constant::lane_select(a, b, c);
214 }
215
217 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
219 constexpr simd<std::uint16_t, 8, Arch> i16x8_relaxed_laneselect(
220 simd<std::uint16_t, 8, Arch> a,
221 simd<std::uint16_t, 8, Arch> b,
222 simd<std::uint16_t, 8, Arch> c) noexcept {
223 if consteval {
224 return detail::wasm_relaxed_constant::lane_select(a, b, c);
225 } else {
227 detail::wasm_relaxed::i16x8_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
228 }
229 }
230
232 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
233 requires { sizeof(simd<std::uint16_t, 8, Arch>); })
237 simd<std::uint16_t, 8, Arch> c) noexcept {
238 return detail::wasm_relaxed_constant::lane_select(a, b, c);
239 }
240
242 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
244 constexpr simd<std::uint32_t, 4, Arch> i32x4_relaxed_laneselect(
245 simd<std::uint32_t, 4, Arch> a,
246 simd<std::uint32_t, 4, Arch> b,
247 simd<std::uint32_t, 4, Arch> c) noexcept {
248 if consteval {
249 return detail::wasm_relaxed_constant::lane_select(a, b, c);
250 } else {
252 detail::wasm_relaxed::i32x4_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
253 }
254 }
255
257 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
258 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
262 simd<std::uint32_t, 4, Arch> c) noexcept {
263 return detail::wasm_relaxed_constant::lane_select(a, b, c);
264 }
265
267 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
269 constexpr simd<std::uint64_t, 2, Arch> i64x2_relaxed_laneselect(
270 simd<std::uint64_t, 2, Arch> a,
271 simd<std::uint64_t, 2, Arch> b,
272 simd<std::uint64_t, 2, Arch> c) noexcept {
273 if consteval {
274 return detail::wasm_relaxed_constant::lane_select(a, b, c);
275 } else {
277 detail::wasm_relaxed::i64x2_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
278 }
279 }
280
282 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
283 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
287 simd<std::uint64_t, 2, Arch> c) noexcept {
288 return detail::wasm_relaxed_constant::lane_select(a, b, c);
289 }
290
292 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
294 constexpr simd<float, 4, Arch> f32x4_relaxed_min(simd<float, 4, Arch> a, simd<float, 4, Arch> b) noexcept {
295 if consteval {
296 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
297 } else {
299 detail::wasm_relaxed::f32x4_relaxed_min<Arch>(a.to_native(), b.to_native()));
300 }
301 }
302
304 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
305 requires { sizeof(simd<float, 4, Arch>); })
307 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
308 }
309
311 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
313 constexpr simd<float, 4, Arch> f32x4_relaxed_max(simd<float, 4, Arch> a, simd<float, 4, Arch> b) noexcept {
314 if consteval {
315 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
316 } else {
318 detail::wasm_relaxed::f32x4_relaxed_max<Arch>(a.to_native(), b.to_native()));
319 }
320 }
321
323 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
324 requires { sizeof(simd<float, 4, Arch>); })
326 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
327 }
328
330 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
332 constexpr simd<double, 2, Arch> f64x2_relaxed_min(simd<double, 2, Arch> a, simd<double, 2, Arch> b) noexcept {
333 if consteval {
334 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
335 } else {
337 detail::wasm_relaxed::f64x2_relaxed_min<Arch>(a.to_native(), b.to_native()));
338 }
339 }
340
342 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
343 requires { sizeof(simd<double, 2, Arch>); })
345 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
346 }
347
349 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
351 constexpr simd<double, 2, Arch> f64x2_relaxed_max(simd<double, 2, Arch> a, simd<double, 2, Arch> b) noexcept {
352 if consteval {
353 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
354 } else {
356 detail::wasm_relaxed::f64x2_relaxed_max<Arch>(a.to_native(), b.to_native()));
357 }
358 }
359
361 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
362 requires { sizeof(simd<double, 2, Arch>); })
364 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
365 }
366
368 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
370 constexpr simd<std::int16_t, 8, Arch> i16x8_relaxed_q15mulr(simd<std::int16_t, 8, Arch> a, simd<std::int16_t, 8, Arch> b) noexcept {
371 if consteval {
372 return detail::wasm_relaxed_constant::q15_multiply(a, b);
373 } else {
375 detail::wasm_relaxed::i16x8_relaxed_q15mulr<Arch>(a.to_native(), b.to_native()));
376 }
377 }
378
380 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
381 requires { sizeof(simd<std::int16_t, 8, Arch>); })
383 return detail::wasm_relaxed_constant::q15_multiply(a, b);
384 }
385
387 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
389 constexpr simd<std::int16_t, 8, Arch> i16x8_relaxed_dot_i8x16_i7x16(simd<std::int8_t, 16, Arch> a, simd<std::uint8_t, 16, Arch> b) noexcept {
390 if consteval {
391 return detail::wasm_relaxed_constant::dot<simd<std::int16_t, 8, Arch>>(a, b);
392 } else {
394 detail::wasm_relaxed::i16x8_relaxed_dot_i8x16_i7x16<Arch>(a.to_native(), b.to_native()));
395 }
396 }
397
399 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
400 requires { sizeof(simd<std::int16_t, 8, Arch>); })
402 return detail::wasm_relaxed_constant::dot<simd<std::int16_t, 8, Arch>>(a, b);
403 }
404
406 template<isa<wasm> Arch> requires(Arch.has(wasm_feature::relaxed_simd))
408 constexpr simd<std::int32_t, 4, Arch> i32x4_relaxed_dot_i8x16_i7x16_add(
409 simd<std::int8_t, 16, Arch> a,
410 simd<std::uint8_t, 16, Arch> b,
411 simd<std::int32_t, 4, Arch> c) noexcept {
412 if consteval {
413 return detail::wasm_relaxed_constant::dot_add(a, b, c);
414 } else {
416 detail::wasm_relaxed::i32x4_relaxed_dot_i8x16_i7x16_add<Arch>(a.to_native(), b.to_native(), c.to_native()));
417 }
418 }
419
421 template<isa<wasm> Arch> requires(!Arch.has(wasm_feature::relaxed_simd) &&
422 requires { sizeof(simd<std::int32_t, 4, Arch>); })
426 simd<std::int32_t, 4, Arch> c) noexcept {
427 return detail::wasm_relaxed_constant::dot_add(a, b, c);
428 }
429
431}
432#endif
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
Definition attributes.h:476
constexpr simd< std::uint32_t, 4, Arch > i32x4_relaxed_laneselect(simd< std::uint32_t, 4, Arch > a, simd< std::uint32_t, 4, Arch > b, simd< std::uint32_t, 4, Arch > c) noexcept
Select with mask c; partial masks permit bit or sign-bit lane selection.
constexpr simd< std::uint32_t, 4, Arch > u32x4_relaxed_trunc_f32x4(simd< float, 4, Arch > a) noexcept
Truncate toward zero; invalid lanes may differ from saturation.
constexpr simd< double, 2, Arch > f64x2_relaxed_madd(simd< double, 2, Arch > a, simd< double, 2, Arch > b, simd< double, 2, Arch > c) noexcept
Compute a * b + c with fused or separate rounding.
constexpr simd< float, 4, Arch > f32x4_relaxed_nmadd(simd< float, 4, Arch > a, simd< float, 4, Arch > b, simd< float, 4, Arch > c) noexcept
Compute -(a * b) + c with fused or separate rounding.
constexpr simd< std::int16_t, 8, Arch > i16x8_relaxed_dot_i8x16_i7x16(simd< std::int8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Pairwise signed-byte dot product; high bits of b have relaxed semantics.
constexpr simd< double, 2, Arch > f64x2_relaxed_max(simd< double, 2, Arch > a, simd< double, 2, Arch > b) noexcept
Maximum with relaxed NaN and signed-zero selection.
constexpr simd< std::uint64_t, 2, Arch > i64x2_relaxed_laneselect(simd< std::uint64_t, 2, Arch > a, simd< std::uint64_t, 2, Arch > b, simd< std::uint64_t, 2, Arch > c) noexcept
Select with mask c; partial masks permit bit or sign-bit lane selection.
constexpr simd< float, 4, Arch > f32x4_relaxed_max(simd< float, 4, Arch > a, simd< float, 4, Arch > b) noexcept
Maximum with relaxed NaN and signed-zero selection.
constexpr simd< std::uint16_t, 8, Arch > i16x8_relaxed_laneselect(simd< std::uint16_t, 8, Arch > a, simd< std::uint16_t, 8, Arch > b, simd< std::uint16_t, 8, Arch > c) noexcept
Select with mask c; partial masks permit bit or sign-bit lane selection.
constexpr simd< std::uint32_t, 4, Arch > u32x4_relaxed_trunc_f64x2_zero(simd< double, 2, Arch > a) noexcept
Truncate toward zero; invalid lanes may differ from saturation.
constexpr simd< float, 4, Arch > f32x4_relaxed_madd(simd< float, 4, Arch > a, simd< float, 4, Arch > b, simd< float, 4, Arch > c) noexcept
Compute a * b + c with fused or separate rounding.
constexpr simd< std::uint8_t, 16, Arch > i8x16_relaxed_laneselect(simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b, simd< std::uint8_t, 16, Arch > c) noexcept
Select with mask c; partial masks permit bit or sign-bit lane selection.
constexpr simd< float, 4, Arch > f32x4_relaxed_min(simd< float, 4, Arch > a, simd< float, 4, Arch > b) noexcept
Minimum with relaxed NaN and signed-zero selection.
constexpr simd< std::int32_t, 4, Arch > i32x4_relaxed_trunc_f32x4(simd< float, 4, Arch > a) noexcept
Truncate toward zero; invalid lanes may differ from saturation.
constexpr simd< std::uint8_t, 16, Arch > i8x16_relaxed_swizzle(simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Select bytes; out-of-range indices have relaxed semantics.
constexpr simd< double, 2, Arch > f64x2_relaxed_nmadd(simd< double, 2, Arch > a, simd< double, 2, Arch > b, simd< double, 2, Arch > c) noexcept
Compute -(a * b) + c with fused or separate rounding.
constexpr simd< std::int32_t, 4, Arch > i32x4_relaxed_dot_i8x16_i7x16_add(simd< std::int8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b, simd< std::int32_t, 4, Arch > c) noexcept
Accumulate two adjacent relaxed dot pairs into c modulo 32 bits.
constexpr simd< std::int16_t, 8, Arch > i16x8_relaxed_q15mulr(simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
Rounded Q15 product; the overflowing -32768 squared case is relaxed.
constexpr simd< std::int32_t, 4, Arch > i32x4_relaxed_trunc_f64x2_zero(simd< double, 2, Arch > a) noexcept
Truncate toward zero; invalid lanes may differ from saturation.
constexpr simd< double, 2, Arch > f64x2_relaxed_min(simd< double, 2, Arch > a, simd< double, 2, Arch > b) noexcept
Minimum with relaxed NaN and signed-zero selection.
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.