Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasmi_core: add support for the Wasm simd proposal #1395

Merged
merged 87 commits into from
Mar 20, 2025
Merged
Changes from 1 commit
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
86a9890
add simd crate feature to wasmi_core crate
Robbepop Mar 16, 2025
5c7a578
implement V128 skeleton
Robbepop Mar 16, 2025
53e526f
rename IntoLane and Lane (appending 's')
Robbepop Mar 16, 2025
769727a
add docs to most (or all) simd.rs definitions
Robbepop Mar 16, 2025
a8c0ae9
add note comments to unsafe transmutes
Robbepop Mar 16, 2025
bc87e4c
implement SIMD splat instructions
Robbepop Mar 16, 2025
d437879
add extract_lane SIMD APIs
Robbepop Mar 17, 2025
64d3c18
expect dead_code warnings
Robbepop Mar 17, 2025
1deaba6
remove empty line
Robbepop Mar 17, 2025
d8b74ad
remove non-existing extract_lane APIs
Robbepop Mar 17, 2025
5952ab1
add replace_lane SIMD APIs
Robbepop Mar 17, 2025
9336f6b
add V128 From impls for bytes and i128
Robbepop Mar 17, 2025
9c15875
add SIMD binary integer math ops
Robbepop Mar 17, 2025
f532fed
add unary integer math SIMD ops
Robbepop Mar 17, 2025
5e55754
add SIMD integer abs ops
Robbepop Mar 17, 2025
2181ab5
add unsigned SIMD lanes types
Robbepop Mar 17, 2025
43635a3
use unsigned SIMD types where applicable for now
Robbepop Mar 17, 2025
0b134b3
improve docs for IntoLanes and IntoLaneIdx
Robbepop Mar 17, 2025
42cc71c
add helper IntoLanewiseWidening trait
Robbepop Mar 17, 2025
ca36c58
clean-up API design
Robbepop Mar 17, 2025
62dea1c
add SIMD ext_mul_{low,high} ops
Robbepop Mar 17, 2025
01cf099
generate docs for new SIMD extmul ops
Robbepop Mar 17, 2025
431ee78
add extadd_pairwise SIMD ops
Robbepop Mar 17, 2025
7dece0a
implement add_sat and sub_sat SIMD ops
Robbepop Mar 17, 2025
2f3c753
add i16x8_q15mulr_sat_s SIMD operation
Robbepop Mar 17, 2025
edd0ea9
add SIMD integer min and max operations
Robbepop Mar 17, 2025
9edb2aa
add SIMD avgr_u ops
Robbepop Mar 17, 2025
2f9f0c0
implement Wasm shift SIMD ops
Robbepop Mar 17, 2025
c4268a8
add bitwise SIMD ops
Robbepop Mar 17, 2025
448cb31
add v128.bitselect SIMD operation
Robbepop Mar 17, 2025
d4bbd34
add SIMD i8x16.popcnt instruction
Robbepop Mar 17, 2025
40b4219
add i32x4.dot_i16x8_s SIMD operation
Robbepop Mar 17, 2025
500d904
implement SIMD reduce ops
Robbepop Mar 17, 2025
707150d
add SIMD comparison instructions
Robbepop Mar 17, 2025
b7e9afc
add unary float SIMD instructions
Robbepop Mar 18, 2025
de36135
move op! macro to top of file
Robbepop Mar 18, 2025
c2bd961
add float binary SIMD instructions
Robbepop Mar 18, 2025
78bf871
Merge branch 'main' into rf-implement-simd-proposal
Robbepop Mar 19, 2025
f992a54
add lanewise unary cast SIMD ops
Robbepop Mar 19, 2025
cf4b5bb
rewrite i32x4.dot_i16x8_s in terms of other fns
Robbepop Mar 19, 2025
c4956ad
add FromNarrow trait and impls
Robbepop Mar 19, 2025
983c271
add V128 convenience methods for FromNarrow
Robbepop Mar 19, 2025
45d3969
rewrite extmul ops in terms of FromNarrow APIs
Robbepop Mar 19, 2025
d275444
rewrite extadd ops in terms of FromNarrow APIs
Robbepop Mar 19, 2025
9d80b48
add new extend SIMD ops
Robbepop Mar 19, 2025
7390796
remove old widening and narrowing APIs
Robbepop Mar 19, 2025
055b579
no longer silence dead_code warnings
Robbepop Mar 19, 2025
9317bbd
add missing docs for convenience method
Robbepop Mar 19, 2025
92e7193
refactor unary widen SIMD ops generation
Robbepop Mar 19, 2025
e953c9f
add more widen-low SIMD ops
Robbepop Mar 19, 2025
df55aac
fix signedness of some SIMD extend-{low,high} ops
Robbepop Mar 19, 2025
8ab2f53
rename macro
Robbepop Mar 19, 2025
e89fa00
add narrowing-low-high SIMD ops
Robbepop Mar 19, 2025
1b47827
rename FromNarrow method
Robbepop Mar 19, 2025
37a3b83
fix i32x4_dot_i16x8_s SIMD impl
Robbepop Mar 19, 2025
9344e29
re-format code
Robbepop Mar 19, 2025
3c5b067
re-write from_low_high impl
Robbepop Mar 19, 2025
9184272
add narrowing low-or SIMD ops
Robbepop Mar 19, 2025
127d340
convert all V128 methods to functions in the simd module
Robbepop Mar 19, 2025
4ec17dc
align docs with others
Robbepop Mar 19, 2025
32e5ced
align more docs
Robbepop Mar 19, 2025
718655e
replace register128 feature with simd feature
Robbepop Mar 19, 2025
3c9ecf7
move load/store stuff into memory.rs module
Robbepop Mar 19, 2025
83230b6
redesign WrapInto and ExtendInto macros
Robbepop Mar 19, 2025
cd11fe2
Merge branch 'main' into rf-implement-simd-proposal
Robbepop Mar 19, 2025
ba56cb9
remove ImmByte since it is unused
Robbepop Mar 19, 2025
aa72956
rename OutOfBoundsLaneId
Robbepop Mar 19, 2025
48c4d4a
merge macro invocations
Robbepop Mar 19, 2025
8055b3d
re-design extmul macros
Robbepop Mar 19, 2025
68da596
refactor macros
Robbepop Mar 19, 2025
52e266e
refactor memory submodule
Robbepop Mar 19, 2025
630481a
Merge branch 'main' into rf-implement-simd-proposal
Robbepop Mar 19, 2025
22cd724
add v128 store instructions
Robbepop Mar 19, 2025
b6b355b
add v128.load evaluators
Robbepop Mar 20, 2025
63601ae
add LaneIndex trait
Robbepop Mar 20, 2025
29ea33b
add more IntoLaneIdx trait impls
Robbepop Mar 20, 2025
f23072c
add impls for v128.load{32,64}_zero
Robbepop Mar 20, 2025
8f01d8a
update docs
Robbepop Mar 20, 2025
f375a29
add v128.loadN_splat instruction impls
Robbepop Mar 20, 2025
62f2895
add v128.loadN_lane SIMD instruction impls
Robbepop Mar 20, 2025
1ac376a
update docs error sections
Robbepop Mar 20, 2025
c5895d0
implement V128 load_mxn_{s,u} ops
Robbepop Mar 20, 2025
fd2d37a
configure Cargo to generate simd docs
Robbepop Mar 20, 2025
c80fcb0
remove value128 crate feature
Robbepop Mar 20, 2025
d25333b
fix avgr SIMD instructions and clippy warnings
Robbepop Mar 20, 2025
d4d95eb
rename some FromNarrow methods to please clippy
Robbepop Mar 20, 2025
b9c5446
add SIMD shuffle and swizzle ops
Robbepop Mar 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add i32x4.dot_i16x8_s SIMD operation
Robbepop committed Mar 17, 2025
commit 40b421939e1954df501e5100aade3467ce62dd57
12 changes: 12 additions & 0 deletions crates/core/src/simd.rs
Original file line number Diff line number Diff line change
@@ -9,44 +9,44 @@
pub struct V128([u8; 16]);

impl From<[u8; 16]> for V128 {
fn from(bytes: [u8; 16]) -> Self {
Self(bytes)

Check warning on line 13 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L12-L13

Added lines #L12 - L13 were not covered by tests
}
}

impl From<i128> for V128 {
fn from(value: i128) -> Self {
Self(value.to_le_bytes())

Check warning on line 19 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L18-L19

Added lines #L18 - L19 were not covered by tests
}
}

impl From<UntypedVal> for V128 {
fn from(value: UntypedVal) -> Self {
let u128 = (u128::from(value.hi64) << 64) | (u128::from(value.lo64));
Self(u128.to_le_bytes())

Check warning on line 26 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L24-L26

Added lines #L24 - L26 were not covered by tests
}
}

impl From<V128> for UntypedVal {
fn from(value: V128) -> Self {
let u128 = u128::from_le_bytes(value.0);
let lo64 = u128 as u64;
let hi64 = (u128 >> 64) as u64;

Check warning on line 34 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L31-L34

Added lines #L31 - L34 were not covered by tests
Self { lo64, hi64 }
}
}

impl ReadAs<V128> for UntypedVal {
fn read_as(&self) -> V128 {

Check warning on line 40 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L40

Added line #L40 was not covered by tests
// Note: we can re-use the `From` impl since both types are of equal size.
V128::from(*self)

Check warning on line 42 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L42

Added line #L42 was not covered by tests
}
}

impl WriteAs<V128> for UntypedVal {
fn write_as(&mut self, value: V128) {

Check warning on line 47 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L47

Added line #L47 was not covered by tests
// Note: we can re-use the `From` impl since both types are of equal size.
*self = UntypedVal::from(value);

Check warning on line 49 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L49

Added line #L49 was not covered by tests
}
}

@@ -73,9 +73,9 @@
) => {
$(
$( #[$attr] )*
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

Check warning on line 76 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L76

Added line #L76 was not covered by tests
#[repr(transparent)]
pub struct $name(u8);

Check warning on line 78 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L78

Added line #L78 was not covered by tests

impl IntoLaneIdx for [(); $n] {
type LaneIdx = $name;
@@ -88,19 +88,19 @@
/// Returns the lane id as `u8`.
///
/// This will never return a `u8` value that is out of bounds for `self`.
pub fn get(self) -> u8 {
self.0 & Self::MASK

Check warning on line 92 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L91-L92

Added lines #L91 - L92 were not covered by tests
}
}

impl TryFrom<u8> for $name {
type Error = OutOfBoundsLaneId;

fn try_from(lane: u8) -> Result<Self, Self::Error> {
if lane > Self::MASK {
return Err(OutOfBoundsLaneId)

Check warning on line 101 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L99-L101

Added lines #L99 - L101 were not covered by tests
}
Ok(Self(lane))

Check warning on line 103 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L103

Added line #L103 was not covered by tests
}
}
)*
@@ -194,7 +194,7 @@
) => {
$(
$( #[$attr] )*
#[derive(Copy, Clone)]

Check warning on line 197 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L197

Added line #L197 was not covered by tests
#[repr(transparent)]
struct $name([$ty; $n]);

@@ -211,7 +211,7 @@
const ALL_ONES: Self::Item = <$ty>::from_le_bytes([0xFF_u8; 16 / $n]);
const ALL_ZEROS: Self::Item = <$ty>::from_le_bytes([0x00_u8; 16 / $n]);

fn from_v128(value: V128) -> Self {

Check warning on line 214 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L214

Added line #L214 was not covered by tests
// SAFETY: the types chosen to implement `Split` are always
// of same size as `V128` and have no invalid bit-patterns.
//
@@ -220,46 +220,46 @@
// out that _not_ using unsafe transmutation confused the
// optimizer enough that optimizations became very flaky.
// This was tested across a variety of compiler versions.
Self(unsafe { ::core::mem::transmute::<V128, [$ty; $n]>(value) })

Check warning on line 223 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L223

Added line #L223 was not covered by tests
}

fn into_v128(self) -> V128 {

Check warning on line 226 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L226

Added line #L226 was not covered by tests
// SAFETY: the types chosen to implement `Combine` are always
// of same size as `V128` and have no invalid bit-patterns.
//
// Note: see note from `from_v128` method above.
unsafe { ::core::mem::transmute::<[$ty; $n], V128>(self.0) }

Check warning on line 231 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L231

Added line #L231 was not covered by tests
}

fn splat(value: Self::Item) -> Self {
Self([value; $n])

Check warning on line 235 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L234-L235

Added lines #L234 - L235 were not covered by tests
}

fn extract_lane(self, lane: Self::LaneIdx) -> Self::Item {
self.0[lane.get() as usize]

Check warning on line 239 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L238-L239

Added lines #L238 - L239 were not covered by tests
}

fn replace_lane(self, lane: Self::LaneIdx, item: Self::Item) -> Self {
let mut this = self;
this.0[lane.get() as usize] = item;
this

Check warning on line 245 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L242-L245

Added lines #L242 - L245 were not covered by tests
}

fn lanewise_unary(self, f: impl Fn(Self::Item) -> Self::Item) -> Self {
let mut this = self.0;
for i in 0..Self::LANES {
this[i] = f(this[i]);

Check warning on line 251 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L248-L251

Added lines #L248 - L251 were not covered by tests
}
Self(this)

Check warning on line 253 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L253

Added line #L253 was not covered by tests
}

fn lanewise_binary(self, other: Self, f: impl Fn(Self::Item, Self::Item) -> Self::Item) -> Self {
let mut lhs = self.0;
let rhs = other.0;
for i in 0..Self::LANES {
lhs[i] = f(lhs[i], rhs[i]);

Check warning on line 260 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L256-L260

Added lines #L256 - L260 were not covered by tests
}
Self(lhs)

Check warning on line 262 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L262

Added line #L262 was not covered by tests
}

fn lanewise_comparison(self, other: Self, f: impl Fn(Self::Item, Self::Item) -> bool) -> Self {
@@ -356,7 +356,7 @@
Self(result)
}

fn lanewise_widening_binary(

Check warning on line 359 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L359

Added line #L359 was not covered by tests
lhs: Self::Narrow,
rhs: Self::Narrow,
f: impl Fn(
@@ -364,14 +364,14 @@
[<Self::Narrow as Lanes>::Item; 2],
) -> Self::Item,
) -> Self {
let a = lhs.0;
let b = rhs.0;

Check warning on line 368 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L367-L368

Added lines #L367 - L368 were not covered by tests
#[rustfmt::skip]
let result = [
f([a[0], a[1]], [b[0], b[1]]),
f([a[2], a[3]], [b[2], b[3]]),

Check warning on line 372 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L370-L372

Added lines #L370 - L372 were not covered by tests
];
Self(result)

Check warning on line 374 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L374

Added line #L374 was not covered by tests
}
}
)*
@@ -395,22 +395,22 @@
impl LanewiseWidening for $ty {
type Narrow = $narrow_ty;

fn lanewise_widening_unary(

Check warning on line 398 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L398

Added line #L398 was not covered by tests
value: Self::Narrow,
f: impl Fn(<Self::Narrow as Lanes>::Item, <Self::Narrow as Lanes>::Item) -> Self::Item,
) -> Self {
let a = value.0;

Check warning on line 402 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L402

Added line #L402 was not covered by tests
#[rustfmt::skip]
let result = [
f(a[0], a[1]),
f(a[2], a[3]),
f(a[4], a[5]),
f(a[6], a[7]),

Check warning on line 408 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L404-L408

Added lines #L404 - L408 were not covered by tests
];
Self(result)

Check warning on line 410 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L410

Added line #L410 was not covered by tests
}

fn lanewise_widening_binary(

Check warning on line 413 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L413

Added line #L413 was not covered by tests
lhs: Self::Narrow,
rhs: Self::Narrow,
f: impl Fn(
@@ -418,16 +418,16 @@
[<Self::Narrow as Lanes>::Item; 2],
) -> Self::Item,
) -> Self {
let a = lhs.0;
let b = rhs.0;

Check warning on line 422 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L421-L422

Added lines #L421 - L422 were not covered by tests
#[rustfmt::skip]
let result = [
f([a[0], a[1]], [b[0], b[1]]),
f([a[2], a[3]], [b[2], b[3]]),
f([a[4], a[5]], [b[4], b[5]]),
f([a[6], a[7]], [b[6], b[7]]),

Check warning on line 428 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L424-L428

Added lines #L424 - L428 were not covered by tests
];
Self(result)

Check warning on line 430 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L430

Added line #L430 was not covered by tests
}
}
)*
@@ -451,26 +451,26 @@
impl LanewiseWidening for $ty {
type Narrow = $narrow_ty;

fn lanewise_widening_unary(

Check warning on line 454 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L454

Added line #L454 was not covered by tests
value: Self::Narrow,
f: impl Fn(<Self::Narrow as Lanes>::Item, <Self::Narrow as Lanes>::Item) -> Self::Item,
) -> Self {
let a = value.0;

Check warning on line 458 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L458

Added line #L458 was not covered by tests
#[rustfmt::skip]
let result = [
f(a[ 0], a[ 1]),
f(a[ 2], a[ 3]),
f(a[ 4], a[ 5]),
f(a[ 6], a[ 7]),
f(a[ 8], a[ 9]),
f(a[10], a[11]),
f(a[12], a[13]),
f(a[14], a[15]),

Check warning on line 468 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L460-L468

Added lines #L460 - L468 were not covered by tests
];
Self(result)

Check warning on line 470 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L470

Added line #L470 was not covered by tests
}

fn lanewise_widening_binary(

Check warning on line 473 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L473

Added line #L473 was not covered by tests
lhs: Self::Narrow,
rhs: Self::Narrow,
f: impl Fn(
@@ -478,20 +478,20 @@
[<Self::Narrow as Lanes>::Item; 2],
) -> Self::Item,
) -> Self {
let a = lhs.0;
let b = rhs.0;

Check warning on line 482 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L481-L482

Added lines #L481 - L482 were not covered by tests
#[rustfmt::skip]
let result = [
f([a[ 0], a[ 1]], [b[ 0], b[ 1]]),
f([a[ 2], a[ 3]], [b[ 2], b[ 3]]),
f([a[ 4], a[ 5]], [b[ 4], b[ 5]]),
f([a[ 6], a[ 7]], [b[ 6], b[ 7]]),
f([a[ 8], a[ 9]], [b[ 8], b[ 9]]),
f([a[10], a[11]], [b[10], b[11]]),
f([a[12], a[13]], [b[12], b[13]]),
f([a[14], a[15]], [b[14], b[15]]),

Check warning on line 492 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L484-L492

Added lines #L484 - L492 were not covered by tests
];
Self(result)

Check warning on line 494 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L494

Added line #L494 was not covered by tests
}
}
)*
@@ -665,65 +665,65 @@

impl V128 {
/// Convenience method to help implement splatting methods.
fn splat<T: IntoLanes>(value: T) -> Self {
<<T as IntoLanes>::Lanes>::splat(value).into_v128()

Check warning on line 669 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L668-L669

Added lines #L668 - L669 were not covered by tests
}

/// Convenience method to help implement lane extraction methods.
fn extract_lane<T: IntoLanes>(self, lane: <T as IntoLanes>::LaneIdx) -> T {
<<T as IntoLanes>::Lanes>::from_v128(self).extract_lane(lane)

Check warning on line 674 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L673-L674

Added lines #L673 - L674 were not covered by tests
}

/// Convenience method to help implement lane replacement methods.
fn replace_lane<T: IntoLanes>(self, lane: <T as IntoLanes>::LaneIdx, item: T) -> Self {
<<T as IntoLanes>::Lanes>::from_v128(self)
.replace_lane(lane, item)

Check warning on line 680 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L678-L680

Added lines #L678 - L680 were not covered by tests
.into_v128()
}

/// Convenience method to help implement lanewise unary methods.
fn lanewise_unary<T: IntoLanes>(self, f: impl Fn(T) -> T) -> Self {
<<T as IntoLanes>::Lanes>::from_v128(self)
.lanewise_unary(f)

Check warning on line 687 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L685-L687

Added lines #L685 - L687 were not covered by tests
.into_v128()
}

/// Convenience method to help implement lanewise binary methods.
fn lanewise_binary<T: IntoLanes>(lhs: Self, rhs: Self, f: impl Fn(T, T) -> T) -> Self {
let lhs = <<T as IntoLanes>::Lanes>::from_v128(lhs);
let rhs = <<T as IntoLanes>::Lanes>::from_v128(rhs);
lhs.lanewise_binary(rhs, f).into_v128()

Check warning on line 695 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L692-L695

Added lines #L692 - L695 were not covered by tests
}

/// Convenience method to help implement lanewise comparison methods.
fn lanewise_comparison<T: IntoLanes>(lhs: Self, rhs: Self, f: impl Fn(T, T) -> bool) -> Self {
let lhs = <<T as IntoLanes>::Lanes>::from_v128(lhs);
let rhs = <<T as IntoLanes>::Lanes>::from_v128(rhs);
lhs.lanewise_comparison(rhs, f).into_v128()

Check warning on line 702 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L699-L702

Added lines #L699 - L702 were not covered by tests
}

/// Convenience method to help implement lanewise unary widening methods.
fn lanewise_widening_unary<T: IntoLanewiseWidening>(

Check warning on line 706 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L706

Added line #L706 was not covered by tests
self,
f: impl Fn(T, T) -> <T as IntoLanewiseWidening>::WideItem,
) -> Self {
<<T as IntoLanewiseWidening>::Wide>::lanewise_widening_unary(
<T as IntoLanes>::Lanes::from_v128(self),
f,

Check warning on line 712 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L711-L712

Added lines #L711 - L712 were not covered by tests
)
.into_v128()
}

/// Convenience method to help implement lanewise binary widening methods.
fn lanewise_widening_binary<T: IntoLanewiseWidening>(

Check warning on line 718 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L718

Added line #L718 was not covered by tests
lhs: Self,
rhs: Self,
f: impl Fn([T; 2], [T; 2]) -> <T as IntoLanewiseWidening>::WideItem,
) -> Self {
<<T as IntoLanewiseWidening>::Wide>::lanewise_widening_binary(
<T as IntoLanes>::Lanes::from_v128(lhs),
<T as IntoLanes>::Lanes::from_v128(rhs),
f,

Check warning on line 726 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L724-L726

Added lines #L724 - L726 were not covered by tests
)
.into_v128()
}
@@ -733,7 +733,7 @@
self,
f: impl Fn(<T::Wide as Lanes>::Item) -> [T::Item; 2],
) -> Self {
T::lanewise_narrowing_unary(<T::Wide as Lanes>::from_v128(self), f).into_v128()

Check warning on line 736 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L736

Added line #L736 was not covered by tests
}

/// Convenience method to help implement lanewise binary narrowing methods.
@@ -743,25 +743,25 @@
f: impl Fn(<T::Wide as Lanes>::Item, <T::Wide as Lanes>::Item) -> [T::Item; 2],
) -> Self {
T::lanewise_narrowing_binary(
<T::Wide as Lanes>::from_v128(lhs),
<T::Wide as Lanes>::from_v128(rhs),
f,

Check warning on line 748 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L746-L748

Added lines #L746 - L748 were not covered by tests
)
.into_v128()
}
}

/// Concenience identity helper function.
fn identity<T>(x: T) -> T {
x

Check warning on line 756 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L755-L756

Added lines #L755 - L756 were not covered by tests
}

macro_rules! impl_splat_for {
( $( fn $name:ident(value: $ty:ty) -> Self; )* ) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(value: $ty) -> Self {
Self::splat(value)

Check warning on line 764 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L763-L764

Added lines #L763 - L764 were not covered by tests
}
)*
};
@@ -781,8 +781,8 @@
( $( fn $name:ident(self, lane: $lane_ty:ty) -> $ret_ty:ty = $convert:expr; )* ) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(self, lane: $lane_ty) -> $ret_ty {
($convert)(self.extract_lane(lane))

Check warning on line 785 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L784-L785

Added lines #L784 - L785 were not covered by tests
}
)*
};
@@ -804,8 +804,8 @@
( $( fn $name:ident(self, lane: $lane_ty:ty, item: $item_ty:ty) -> Self; )* ) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(self, lane: $lane_ty, item: $item_ty) -> Self {
self.replace_lane(lane, item)

Check warning on line 808 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L807-L808

Added lines #L807 - L808 were not covered by tests
}
)*
};
@@ -825,24 +825,24 @@
( $( fn $name:ident(self) -> Self = $lanewise_expr:expr; )* ) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(self) -> Self {
Self::lanewise_unary(self, $lanewise_expr)

Check warning on line 829 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L828-L829

Added lines #L828 - L829 were not covered by tests
}
)*
};
}

/// Lanewise operation for the Wasm `q15mulr_sat` SIMD operation.
fn i16x8_q15mulr_sat(x: i16, y: i16) -> i16 {
(x * y + 0x4000) >> 15

Check warning on line 837 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L836-L837

Added lines #L836 - L837 were not covered by tests
}

macro_rules! impl_binary_for {
( $( fn $name:ident(lhs: Self, rhs: Self) -> Self = $lanewise_expr:expr; )* ) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(lhs: Self, rhs: Self) -> Self {
Self::lanewise_binary(lhs, rhs, $lanewise_expr)

Check warning on line 845 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L844-L845

Added lines #L844 - L845 were not covered by tests
}
)*
};
@@ -888,13 +888,13 @@
fn i32x4_max_s(lhs: Self, rhs: Self) -> Self = i32::max;
fn i32x4_max_u(lhs: Self, rhs: Self) -> Self = u32::max;

fn i8x16_avgr_u(lhs: Self, rhs: Self) -> Self = |a: u8, b: u8| (a + b + 1) / 2;
fn i16x8_avgr_u(lhs: Self, rhs: Self) -> Self = |a: u16, b: u16| (a + b + 1) / 2;

Check warning on line 892 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L891-L892

Added lines #L891 - L892 were not covered by tests

fn v128_and(lhs: Self, rhs: Self) -> Self = <i64 as BitAnd>::bitand;
fn v128_or(lhs: Self, rhs: Self) -> Self = <i64 as BitOr>::bitor;
fn v128_xor(lhs: Self, rhs: Self) -> Self = <i64 as BitXor>::bitxor;
fn v128_andnot(lhs: Self, rhs: Self) -> Self = |a: i64, b: i64| a & !b;

Check warning on line 897 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L897

Added line #L897 was not covered by tests
}

impl_unary_for! {
@@ -910,7 +910,7 @@

fn v128_not(self) -> Self = <i64 as Not>::not;

fn i8x16_popcnt(self) -> Self = |v: u8| v.count_ones() as u8;

Check warning on line 913 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L913

Added line #L913 was not covered by tests
}
}

@@ -926,23 +926,23 @@
) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($extmul_low), "` instruction.")]
pub fn $extmul_low(lhs: Self, rhs: Self) -> Self {
fn extmul(a: [$narrow; 2], b: [$narrow; 2]) -> $wide {
let a = <$wide>::from(a[0]);
let b = <$wide>::from(b[0]);
a.wrapping_mul(b)

Check warning on line 933 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L929-L933

Added lines #L929 - L933 were not covered by tests
}
Self::lanewise_widening_binary(lhs, rhs, extmul)

Check warning on line 935 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L935

Added line #L935 was not covered by tests
}

#[doc = concat!("Executes a Wasm `", stringify!($extmul_high), "` instruction.")]
pub fn $extmul_high(lhs: Self, rhs: Self) -> Self {
fn extmul(a: [$narrow; 2], b: [$narrow; 2]) -> $wide {
let a = <$wide>::from(a[1]);
let b = <$wide>::from(b[1]);
a.wrapping_mul(b)

Check warning on line 943 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L939-L943

Added lines #L939 - L943 were not covered by tests
}
Self::lanewise_widening_binary(lhs, rhs, extmul)

Check warning on line 945 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L945

Added line #L945 was not covered by tests
}
)*
};
@@ -988,13 +988,13 @@
) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(self) -> Self {
fn extadd_pairwise(a: $narrow, b: $narrow) -> $wide {
let a = <$wide>::from(a);
let b = <$wide>::from(b);
a.wrapping_add(b)

Check warning on line 995 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L991-L995

Added lines #L991 - L995 were not covered by tests
}
self.lanewise_widening_unary(extadd_pairwise)

Check warning on line 997 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L997

Added line #L997 was not covered by tests
}
)*
};
@@ -1014,8 +1014,8 @@
) => {
$(
#[doc = concat!("Executes a Wasm `", stringify!($name), "` instruction.")]
pub fn $name(self, rhs: u32) -> Self {
self.lanewise_unary(|v| $lanewise_expr(v, rhs))

Check warning on line 1018 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L1017-L1018

Added lines #L1017 - L1018 were not covered by tests
}
)*
};
@@ -1038,8 +1038,20 @@
}

impl V128 {
/// Execute a Wasm `i32x4.dot_i16x8_s` instruction.
pub fn i32x4_dot_i16x8_s(lhs: Self, rhs: Self) -> Self {
fn dot(a: [i16; 2], b: [i16; 2]) -> i32 {
let a = a.map(i32::from);
let b = b.map(i32::from);
let dot0 = a[0].wrapping_mul(b[0]);
let dot1 = a[1].wrapping_mul(b[1]);
dot0.wrapping_add(dot1)

Check warning on line 1048 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L1042-L1048

Added lines #L1042 - L1048 were not covered by tests
}
Self::lanewise_widening_binary(lhs, rhs, dot)

Check warning on line 1050 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L1050

Added line #L1050 was not covered by tests
}

/// Execute a Wasm `v128.bitselect` instruction.
pub fn v128_bitselect(v1: Self, v2: Self, c: Self) -> Self {
Self::v128_or(Self::v128_and(v1, c), Self::v128_andnot(v2, c))

Check warning on line 1055 in crates/core/src/simd.rs

Codecov / codecov/patch

crates/core/src/simd.rs#L1054-L1055

Added lines #L1054 - L1055 were not covered by tests
}
}