generic_simd/arch/wasm/
mod.rs1#[cfg(feature = "complex")]
4mod complex;
5#[cfg(feature = "complex")]
6pub use complex::*;
7
8use crate::{
9 arch::{generic, Token},
10 scalar::Scalar,
11 shim::{Shim2, Shim4, ShimToken},
12 vector::{width, Native, Vector},
13};
14use core::arch::wasm32::*;
15
16#[derive(Copy, Clone, Debug)]
18pub struct Simd128(());
19
20impl_token! { Simd128 => "simd128" }
21
22impl Native<Simd128> for f32 {
23 type Width = width::W4;
24}
25
26impl Native<Simd128> for f64 {
27 type Width = width::W2;
28}
29
30#[derive(Clone, Copy, Debug)]
32#[repr(transparent)]
33#[allow(non_camel_case_types)]
34pub struct f32x4(v128);
35
36#[derive(Clone, Copy, Debug)]
38#[repr(transparent)]
39#[allow(non_camel_case_types)]
40pub struct f64x2(v128);
41
42impl Scalar<Simd128, width::W1> for f32 {
43 type Vector = ShimToken<generic::f32x1, Self, Simd128>;
44}
45
46impl Scalar<Simd128, width::W2> for f32 {
47 type Vector = ShimToken<Shim2<generic::f32x1, Self>, Self, Simd128>;
48}
49
50impl Scalar<Simd128, width::W4> for f32 {
51 type Vector = f32x4;
52}
53
54impl Scalar<Simd128, width::W8> for f32 {
55 type Vector = Shim2<f32x4, f32>;
56}
57
58impl Scalar<Simd128, width::W1> for f64 {
59 type Vector = ShimToken<generic::f64x1, Self, Simd128>;
60}
61
62impl Scalar<Simd128, width::W2> for f64 {
63 type Vector = f64x2;
64}
65
66impl Scalar<Simd128, width::W4> for f64 {
67 type Vector = Shim2<f64x2, f64>;
68}
69
70impl Scalar<Simd128, width::W8> for f64 {
71 type Vector = Shim4<f64x2, f64>;
72}
73
74as_slice! { f32x4 }
75as_slice! { f64x2 }
76
77unsafe impl Vector for f32x4 {
78 type Scalar = f32;
79 type Token = Simd128;
80 type Width = width::W4;
81 type Underlying = v128;
82
83 #[inline]
84 fn zeroed(_: Self::Token) -> Self {
85 Self(unsafe { f32x4_splat(0.) })
86 }
87
88 #[inline]
89 fn splat(_: Self::Token, value: Self::Scalar) -> Self {
90 Self(unsafe { f32x4_splat(value) })
91 }
92}
93
94unsafe impl Vector for f64x2 {
95 type Scalar = f64;
96 type Token = Simd128;
97 type Width = width::W2;
98 type Underlying = v128;
99
100 #[inline]
101 fn zeroed(_: Self::Token) -> Self {
102 Self(unsafe { f64x2_splat(0.) })
103 }
104
105 #[inline]
106 fn splat(_: Self::Token, value: Self::Scalar) -> Self {
107 Self(unsafe { f64x2_splat(value) })
108 }
109}
110
111arithmetic_ops! {
112 feature: Simd128::new_unchecked(),
113 for f32x4:
114 add -> (f32x4_add),
115 sub -> (f32x4_sub),
116 mul -> (f32x4_mul),
117 div -> (f32x4_div)
118}
119
120arithmetic_ops! {
121 feature: Simd128::new_unchecked(),
122 for f64x2:
123 add -> (f64x2_add),
124 sub -> (f64x2_sub),
125 mul -> (f64x2_mul),
126 div -> (f64x2_div)
127}
128
129impl core::ops::Neg for f32x4 {
130 type Output = Self;
131
132 #[inline]
133 fn neg(self) -> Self {
134 Self(unsafe { f32x4_neg(self.0) })
135 }
136}
137
138impl core::ops::Neg for f64x2 {
139 type Output = Self;
140
141 #[inline]
142 fn neg(self) -> Self {
143 Self(unsafe { f64x2_neg(self.0) })
144 }
145}