Skip to content

Commit

Permalink
Use WebAssembly SIMD instructions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
CryZe committed May 25, 2021
1 parent 2e6aa24 commit 639940a
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ See the `examples/` directory for usage examples.
#![allow(clippy::neg_cmp_op_on_partial_ord)]
#![allow(clippy::too_many_arguments)]

#![cfg_attr(target_arch = "wasm32", feature(wasm_simd))]

#[cfg(not(any(feature = "std", feature = "libm")))]
compile_error!("You have to activate either the `std` or the `libm` feature.");

Expand Down
41 changes: 41 additions & 0 deletions src/wide/f32x4_t.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ cfg_if::cfg_if! {
#[derive(Default, Clone, Copy, PartialEq, Debug)]
#[repr(C, align(16))]
pub struct f32x4(m128);
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
use core::arch::wasm32::*;

// repr(transparent) allows for directly passing the v128 on the WASM stack.
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct f32x4(v128);

impl Default for f32x4 {
fn default() -> Self {
Self::splat(0.0)
}
}

impl PartialEq for f32x4 {
fn eq(&self, other: &Self) -> bool {
unsafe {
i32x4_all_true(f32x4_eq(self.0, other.0))
}
}
}
} else {
#[derive(Default, Clone, Copy, PartialEq, Debug)]
#[repr(C, align(16))]
Expand All @@ -33,6 +54,10 @@ impl f32x4 {
cfg_if::cfg_if! {
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
Self(max_m128(self.0, rhs.0))
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
unsafe {
Self(f32x4_max(self.0, rhs.0))
}
} else {
Self([
self.0[0].max(rhs.0[0]),
Expand All @@ -48,6 +73,10 @@ impl f32x4 {
cfg_if::cfg_if! {
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
Self(min_m128(self.0, rhs.0))
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
unsafe {
Self(f32x4_min(self.0, rhs.0))
}
} else {
Self([
self.0[0].min(rhs.0[0]),
Expand Down Expand Up @@ -79,6 +108,10 @@ impl core::ops::Add for f32x4 {
cfg_if::cfg_if! {
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
Self(add_m128(self.0, rhs.0))
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
unsafe {
Self(f32x4_add(self.0, rhs.0))
}
} else {
Self([
self.0[0] + rhs.0[0],
Expand All @@ -104,6 +137,10 @@ impl core::ops::Sub for f32x4 {
cfg_if::cfg_if! {
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
Self(sub_m128(self.0, rhs.0))
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
unsafe {
Self(f32x4_sub(self.0, rhs.0))
}
} else {
Self([
self.0[0] - rhs.0[0],
Expand All @@ -123,6 +160,10 @@ impl core::ops::Mul for f32x4 {
cfg_if::cfg_if! {
if #[cfg(all(feature = "simd", target_feature = "sse"))] {
Self(mul_m128(self.0, rhs.0))
} else if #[cfg(all(feature = "simd", target_feature = "simd128"))] {
unsafe {
Self(f32x4_mul(self.0, rhs.0))
}
} else {
Self([
self.0[0] * rhs.0[0],
Expand Down
Loading

0 comments on commit 639940a

Please sign in to comment.