4#include "native/isa_import.h"
5#include "native/wasm/relaxed.h"
11#if NATIVE_HOST_WASM || defined(NATIVE_DOXYGEN)
21 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
25 return detail::wasm_relaxed_constant::swizzle(a, b);
28 detail::wasm_relaxed::i8x16_relaxed_swizzle<Arch>(a.to_native(), b.to_native()));
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);
40 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
44 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
47 detail::wasm_relaxed::i32x4_relaxed_trunc_f32x4<Arch>(a.to_native()));
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);
59 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
63 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
66 detail::wasm_relaxed::u32x4_relaxed_trunc_f32x4<Arch>(a.to_native()));
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);
78 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
82 return detail::wasm_relaxed_constant::truncation<simd<std::int32_t, 4, Arch>>(a);
85 detail::wasm_relaxed::i32x4_relaxed_trunc_f64x2_zero<Arch>(a.to_native()));
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);
97 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
101 return detail::wasm_relaxed_constant::truncation<simd<std::uint32_t, 4, Arch>>(a);
104 detail::wasm_relaxed::u32x4_relaxed_trunc_f64x2_zero<Arch>(a.to_native()));
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);
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 {
120 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
123 detail::wasm_relaxed::f32x4_relaxed_madd<Arch>(a.to_native(), b.to_native(), c.to_native()));
128 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
129 requires {
sizeof(simd<float, 4, Arch>); })
130 native_nodiscard consteval simd<float, 4, Arch> f32x4_relaxed_madd(
simd<float, 4, Arch> a,
simd<float, 4, Arch> b,
simd<float, 4, Arch> c)
noexcept {
131 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
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 {
139 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
142 detail::wasm_relaxed::f32x4_relaxed_nmadd<Arch>(a.to_native(), b.to_native(), c.to_native()));
147 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
148 requires {
sizeof(simd<float, 4, Arch>); })
149 native_nodiscard consteval simd<float, 4, Arch> f32x4_relaxed_nmadd(
simd<float, 4, Arch> a,
simd<float, 4, Arch> b,
simd<float, 4, Arch> c)
noexcept {
150 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
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 {
158 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
161 detail::wasm_relaxed::f64x2_relaxed_madd<Arch>(a.to_native(), b.to_native(), c.to_native()));
166 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
167 requires {
sizeof(simd<double, 2, Arch>); })
168 native_nodiscard consteval simd<double, 2, Arch> f64x2_relaxed_madd(
simd<double, 2, Arch> a,
simd<double, 2, Arch> b,
simd<double, 2, Arch> c)
noexcept {
169 return detail::wasm_relaxed_constant::multiply_add<false>(a, b, c);
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 {
177 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
180 detail::wasm_relaxed::f64x2_relaxed_nmadd<Arch>(a.to_native(), b.to_native(), c.to_native()));
185 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
186 requires {
sizeof(simd<double, 2, Arch>); })
187 native_nodiscard consteval simd<double, 2, Arch> f64x2_relaxed_nmadd(
simd<double, 2, Arch> a,
simd<double, 2, Arch> b,
simd<double, 2, Arch> c)
noexcept {
188 return detail::wasm_relaxed_constant::multiply_add<true>(a, b, c);
192 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
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 {
199 return detail::wasm_relaxed_constant::lane_select(a, b, c);
202 detail::wasm_relaxed::i8x16_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
207 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
208 requires {
sizeof(simd<std::uint8_t, 16, Arch>); })
213 return detail::wasm_relaxed_constant::lane_select(a, b, c);
217 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
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 {
224 return detail::wasm_relaxed_constant::lane_select(a, b, c);
227 detail::wasm_relaxed::i16x8_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
232 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
233 requires {
sizeof(simd<std::uint16_t, 8, Arch>); })
238 return detail::wasm_relaxed_constant::lane_select(a, b, c);
242 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
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 {
249 return detail::wasm_relaxed_constant::lane_select(a, b, c);
252 detail::wasm_relaxed::i32x4_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
257 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
258 requires {
sizeof(simd<std::uint32_t, 4, Arch>); })
263 return detail::wasm_relaxed_constant::lane_select(a, b, c);
267 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
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 {
274 return detail::wasm_relaxed_constant::lane_select(a, b, c);
277 detail::wasm_relaxed::i64x2_relaxed_laneselect<Arch>(a.to_native(), b.to_native(), c.to_native()));
282 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
283 requires {
sizeof(simd<std::uint64_t, 2, Arch>); })
288 return detail::wasm_relaxed_constant::lane_select(a, b, c);
292 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
296 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
299 detail::wasm_relaxed::f32x4_relaxed_min<Arch>(a.to_native(), b.to_native()));
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);
311 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
315 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
318 detail::wasm_relaxed::f32x4_relaxed_max<Arch>(a.to_native(), b.to_native()));
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);
330 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
334 return detail::wasm_relaxed_constant::minimum_maximum<false>(a, b);
337 detail::wasm_relaxed::f64x2_relaxed_min<Arch>(a.to_native(), b.to_native()));
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);
349 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
353 return detail::wasm_relaxed_constant::minimum_maximum<true>(a, b);
356 detail::wasm_relaxed::f64x2_relaxed_max<Arch>(a.to_native(), b.to_native()));
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);
368 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
372 return detail::wasm_relaxed_constant::q15_multiply(a, b);
375 detail::wasm_relaxed::i16x8_relaxed_q15mulr<Arch>(a.to_native(), b.to_native()));
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);
387 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
391 return detail::wasm_relaxed_constant::dot<simd<std::int16_t, 8, Arch>>(a, b);
394 detail::wasm_relaxed::i16x8_relaxed_dot_i8x16_i7x16<Arch>(a.to_native(), b.to_native()));
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);
406 template<isa<wasm> Arch>
requires(Arch.has(wasm_feature::relaxed_simd))
410 simd<
std::uint8_t, 16, Arch> b,
411 simd<
std::int32_t, 4, Arch> c) noexcept {
413 return detail::wasm_relaxed_constant::dot_add(a, b, c);
416 detail::wasm_relaxed::i32x4_relaxed_dot_i8x16_i7x16_add<Arch>(a.to_native(), b.to_native(), c.to_native()));
421 template<isa<wasm> Arch>
requires(!Arch.has(wasm_feature::relaxed_simd) &&
422 requires {
sizeof(simd<std::int32_t, 4, Arch>); })
427 return detail::wasm_relaxed_constant::dot_add(a, b, c);
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
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.