Skip to content

Commit 639940a

Browse files
committed
Use WebAssembly SIMD instructions
WebAssembly SIMD is almost here. Chrome 91 releases today. It is the first browser to ship WASM SIMD. Firefox 89 will follow in a bit over a week as well. Rust also intends to stabilize these instructions very soon. Until then this PR will stay WIP.
1 parent 2e6aa24 commit 639940a

File tree

5 files changed

+295
-20
lines changed

5 files changed

+295
-20
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ See the `examples/` directory for usage examples.
2828
#![allow(clippy::neg_cmp_op_on_partial_ord)]
2929
#![allow(clippy::too_many_arguments)]
3030

31+
#![cfg_attr(target_arch = "wasm32", feature(wasm_simd))]
32+
3133
#[cfg(not(any(feature = "std", feature = "libm")))]
3234
compile_error!("You have to activate either the `std` or the `libm` feature.");
3335

src/wide/f32x4_t.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,27 @@ cfg_if::cfg_if! {
1414
#[derive(Default, Clone, Copy, PartialEq, Debug)]
1515
#[repr(C, align(16))]
1616
pub struct f32x4(m128);
17+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
18+
use core::arch::wasm32::*;
19+
20+
// repr(transparent) allows for directly passing the v128 on the WASM stack.
21+
#[derive(Clone, Copy, Debug)]
22+
#[repr(transparent)]
23+
pub struct f32x4(v128);
24+
25+
impl Default for f32x4 {
26+
fn default() -> Self {
27+
Self::splat(0.0)
28+
}
29+
}
30+
31+
impl PartialEq for f32x4 {
32+
fn eq(&self, other: &Self) -> bool {
33+
unsafe {
34+
i32x4_all_true(f32x4_eq(self.0, other.0))
35+
}
36+
}
37+
}
1738
} else {
1839
#[derive(Default, Clone, Copy, PartialEq, Debug)]
1940
#[repr(C, align(16))]
@@ -33,6 +54,10 @@ impl f32x4 {
3354
cfg_if::cfg_if! {
3455
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
3556
Self(max_m128(self.0, rhs.0))
57+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
58+
unsafe {
59+
Self(f32x4_max(self.0, rhs.0))
60+
}
3661
} else {
3762
Self([
3863
self.0[0].max(rhs.0[0]),
@@ -48,6 +73,10 @@ impl f32x4 {
4873
cfg_if::cfg_if! {
4974
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
5075
Self(min_m128(self.0, rhs.0))
76+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
77+
unsafe {
78+
Self(f32x4_min(self.0, rhs.0))
79+
}
5180
} else {
5281
Self([
5382
self.0[0].min(rhs.0[0]),
@@ -79,6 +108,10 @@ impl core::ops::Add for f32x4 {
79108
cfg_if::cfg_if! {
80109
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
81110
Self(add_m128(self.0, rhs.0))
111+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
112+
unsafe {
113+
Self(f32x4_add(self.0, rhs.0))
114+
}
82115
} else {
83116
Self([
84117
self.0[0] + rhs.0[0],
@@ -104,6 +137,10 @@ impl core::ops::Sub for f32x4 {
104137
cfg_if::cfg_if! {
105138
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
106139
Self(sub_m128(self.0, rhs.0))
140+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
141+
unsafe {
142+
Self(f32x4_sub(self.0, rhs.0))
143+
}
107144
} else {
108145
Self([
109146
self.0[0] - rhs.0[0],
@@ -123,6 +160,10 @@ impl core::ops::Mul for f32x4 {
123160
cfg_if::cfg_if! {
124161
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
125162
Self(mul_m128(self.0, rhs.0))
163+
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
164+
unsafe {
165+
Self(f32x4_mul(self.0, rhs.0))
166+
}
126167
} else {
127168
Self([
128169
self.0[0] * rhs.0[0],

0 commit comments

Comments
 (0)