diff options
| -rw-r--r-- | crates/cli/src/cli.rs | 10 | ||||
| -rw-r--r-- | crates/cli/src/wast_runner.rs | 10 | ||||
| -rw-r--r-- | crates/parser/src/module.rs | 3 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 10 | ||||
| -rw-r--r-- | crates/tinywasm/benches/tinywasm.rs | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/error.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/instance.rs | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/executor.rs | 9 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/num_helpers.rs | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/simd/instructions.rs | 171 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/simd/macros.rs | 64 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/simd/mod.rs | 39 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/stack/value_stack.rs | 8 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/values.rs | 6 | ||||
| -rw-r--r-- | crates/tinywasm/src/reference.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/store/memory/instance.rs | 11 | ||||
| -rw-r--r-- | crates/tinywasm/src/store/memory/mod.rs | 14 | ||||
| -rw-r--r-- | crates/tinywasm/tests/host_func_signature_check.rs | 6 | ||||
| -rw-r--r-- | crates/tinywasm/tests/resume_execution.rs | 3 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 1 |
20 files changed, 243 insertions, 143 deletions
diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index 8b9df2d..ae367d2 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -1,10 +1,6 @@ -use clap::{ - Args, Parser, Subcommand, ValueEnum, - builder::{ - Styles, - styling::{AnsiColor, Effects}, - }, -}; +use clap::builder::Styles; +use clap::builder::styling::{AnsiColor, Effects}; +use clap::{Args, Parser, Subcommand, ValueEnum}; use clap_complete::Shell; use crate::engine_flags::EngineFlags; diff --git a/crates/cli/src/wast_runner.rs b/crates/cli/src/wast_runner.rs index 9170dce..0634e76 100644 --- a/crates/cli/src/wast_runner.rs +++ b/crates/cli/src/wast_runner.rs @@ -1,11 +1,9 @@ use std::collections::{BTreeMap, HashMap}; use std::fmt::{Display, Formatter}; use std::fs::canonicalize; +use std::panic::{self, AssertUnwindSafe}; use std::path::PathBuf; -use std::{ - panic::{self, AssertUnwindSafe}, - time::Duration, -}; +use std::time::Duration; use eyre::{Context, Result, bail, eyre}; use log::{debug, error}; @@ -833,9 +831,11 @@ impl FloatToken for wast::token::F32 { fn bits(&self) -> Bits { Bits::U32(self.bits) } + fn canonical_nan() -> WasmValue { WasmValue::F32(f32::NAN) } + fn arithmetic_nan() -> WasmValue { WasmValue::F32(f32::NAN) } @@ -845,9 +845,11 @@ impl FloatToken for wast::token::F64 { fn bits(&self) -> Bits { Bits::U64(self.bits) } + fn canonical_nan() -> WasmValue { WasmValue::F64(f64::NAN) } + fn arithmetic_nan() -> WasmValue { WasmValue::F64(f64::NAN) } diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index fab6258..4030a72 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -1,7 +1,6 @@ use crate::log::debug; use crate::{ParseError, ParserOptions, Result, conversion::*, optimize}; -use alloc::sync::Arc; -use alloc::{boxed::Box, format, string::ToString, vec::Vec}; +use alloc::{boxed::Box, format, string::ToString, sync::Arc, vec::Vec}; use core::marker::PhantomData; use core::ops::Range; use tinywasm_types::*; diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 5fddad9..4d233d3 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -63,6 +63,7 @@ fn operand_size(ty: wasmparser::ValType) -> OperandSize { impl<'a, R: WasmModuleResources> VisitOperator<'a> for ValidateThenVisit<'_, R> { type Output = (); + wasmparser::for_each_visit_operator!(validate_then_visit); fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { @@ -113,12 +114,13 @@ pub(crate) struct FunctionBuilder<R> { impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuilder<R> { type Output = (); - wasmparser::for_each_visit_operator!(impl_visit_operator); fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { Some(self) } + wasmparser::for_each_visit_operator!(impl_visit_operator); + define_mem_operands! { visit_i32_load(I32Load), visit_i64_load(I64Load), visit_f32_load(F32Load), visit_f64_load(F64Load), visit_i32_load8_s(I32Load8S), visit_i32_load8_u(I32Load8U), visit_i32_load16_s(I32Load16S), @@ -467,10 +469,12 @@ impl<R: WasmModuleResources> wasmparser::VisitSimdOperator<'_> for FunctionBuild define_mem_operands_simd! { visit_v128_load(V128Load), visit_v128_load8x8_s(V128Load8x8S), visit_v128_load8x8_u(V128Load8x8U), visit_v128_load16x4_s(V128Load16x4S), visit_v128_load16x4_u(V128Load16x4U), visit_v128_load32x2_s(V128Load32x2S), visit_v128_load32x2_u(V128Load32x2U), visit_v128_load8_splat(V128Load8Splat), visit_v128_load16_splat(V128Load16Splat), visit_v128_load32_splat(V128Load32Splat), visit_v128_load64_splat(V128Load64Splat), visit_v128_load32_zero(V128Load32Zero), visit_v128_load64_zero(V128Load64Zero), visit_v128_store(V128Store) } + define_mem_operands_simd_lane! { visit_v128_load8_lane(V128Load8Lane), visit_v128_load16_lane(V128Load16Lane), visit_v128_load32_lane(V128Load32Lane), visit_v128_load64_lane(V128Load64Lane), visit_v128_store8_lane(V128Store8Lane), visit_v128_store16_lane(V128Store16Lane), visit_v128_store32_lane(V128Store32Lane), visit_v128_store64_lane(V128Store64Lane) } + define_operands! { visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_andnot(V128AndNot), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), visit_i8x16_splat(I8x16Splat), visit_i8x16_swizzle(I8x16Swizzle), visit_i8x16_eq(I8x16Eq), visit_i8x16_ne(I8x16Ne), visit_i8x16_lt_s(I8x16LtS), visit_i8x16_lt_u(I8x16LtU), visit_i8x16_gt_s(I8x16GtS), visit_i8x16_gt_u(I8x16GtU), visit_i8x16_le_s(I8x16LeS), visit_i8x16_le_u(I8x16LeU), visit_i8x16_ge_s(I8x16GeS), visit_i8x16_ge_u(I8x16GeU), @@ -554,7 +558,9 @@ impl<R: WasmModuleResources> FunctionBuilder<R> { } fn stack_base_at_frame(&self, depth: usize) -> StackBase { - let Some(frame) = self.validator.get_control_frame(depth) else { return StackBase::default() }; + let Some(frame) = self.validator.get_control_frame(depth) else { + return StackBase::default(); + }; let mut base = StackBase::default(); let stack_height = self.validator.operand_stack_height() as usize; for i in 0..frame.height { diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index 7d50d72..9a4de80 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,8 +1,7 @@ use criterion::{Criterion, criterion_group, criterion_main}; use eyre::Result; -use tinywasm::{ - Engine, FuncContext, HostFunction, Imports, MemoryBackend, ModuleInstance, Store, engine::Config, types, -}; +use tinywasm::engine::Config; +use tinywasm::{Engine, FuncContext, HostFunction, Imports, MemoryBackend, ModuleInstance, Store, types}; use types::Module; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.wasm"); diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index adac5a7..b26da42 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -2,8 +2,7 @@ use alloc::boxed::Box; use alloc::string::{String, ToString}; use alloc::sync::Arc; use alloc::vec::Vec; -use core::fmt::Debug; -use core::fmt::Display; +use core::fmt::{Debug, Display}; use tinywasm_types::FuncType; use tinywasm_types::archive::TwasmError; diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 179f0c7..b75127f 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -1,8 +1,5 @@ +use alloc::{boxed::Box, format, rc::Rc, sync::Arc}; use core::hint::cold_path; - -use alloc::boxed::Box; -use alloc::sync::Arc; -use alloc::{format, rc::Rc}; use tinywasm_types::*; use crate::func::{FromWasmValues, IntoWasmValues, ToWasmTypes}; diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index f4e1352..dd45f74 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -1243,6 +1243,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { fn exec_const<T: InternalValue>(&mut self, val: T) -> Result<(), Trap> { self.store.value_stack.push(val) } + fn exec_ref_is_null(&mut self) -> Result<(), Trap> { let is_null = i32::from(<ValueRef>::stack_pop(&mut self.store.value_stack).is_null()); self.store.value_stack.push::<i32>(is_null) @@ -1255,6 +1256,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { false => self.store.value_stack.push::<i32>(mem.page_count as i32), } } + fn exec_memory_grow(&mut self, addr: u32) -> Result<(), Trap> { let mem = self.store.state.get_mem_mut(self.module.resolve_mem_addr(addr)); let is_64bit = mem.is_64bit(); @@ -1290,6 +1292,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { } Ok(()) } + fn exec_memory_fill(&mut self, addr: u32) -> Result<(), Trap> { let size = i32::stack_pop(&mut self.store.value_stack); let val = i32::stack_pop(&mut self.store.value_stack); @@ -1351,6 +1354,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { } Ok(()) } + fn exec_table_copy(&mut self, dst_table: u32, src_table: u32) -> Result<(), Trap> { let size = i32::stack_pop(&mut self.store.value_stack); let src = i32::stack_pop(&mut self.store.value_stack); @@ -1473,16 +1477,19 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { let v = table.get_wasm_val(idx as u32)?; self.store.value_stack.push_dyn(v.into()) } + fn exec_table_set(&mut self, table_index: u32) -> Result<(), Trap> { let val = <ValueRef>::stack_pop(&mut self.store.value_stack); let idx = <i32>::stack_pop(&mut self.store.value_stack) as u32; let table = self.store.state.get_table_mut(self.module.resolve_table_addr(table_index)); table.set(idx, val.addr().into()) } + fn exec_table_size(&mut self, table_index: u32) -> Result<(), Trap> { let table = self.store.state.get_table(self.module.resolve_table_addr(table_index)); self.store.value_stack.push(table.size()) } + fn exec_table_init(&mut self, elem_index: u32, table_index: u32) -> Result<(), Trap> { let size = i32::stack_pop(&mut self.store.value_stack); // n let offset = i32::stack_pop(&mut self.store.value_stack); // s @@ -1517,6 +1524,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { table.init(i64::from(dst), &items[offset as usize..(offset + size) as usize]) } + fn exec_table_grow(&mut self, table_index: u32) -> Result<(), Trap> { let table = self.store.state.get_table_mut(self.module.resolve_table_addr(table_index)); let sz = table.size(); @@ -1527,6 +1535,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { Err(_) => self.store.value_stack.push(-1_i32), } } + fn exec_table_fill(&mut self, table_index: u32) -> Result<(), Trap> { let table = self.store.state.get_table_mut(self.module.resolve_table_addr(table_index)); diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index c88d7e4..74bca57 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -1,7 +1,4 @@ -pub(crate) trait TinywasmIntExt -where - Self: Sized, -{ +pub(crate) trait TinywasmIntExt: Sized { fn checked_wrapping_rem(self, rhs: Self) -> Result<Self, Trap>; fn wasm_checked_div(self, rhs: Self) -> Result<Self, Trap>; } diff --git a/crates/tinywasm/src/interpreter/simd/instructions.rs b/crates/tinywasm/src/interpreter/simd/instructions.rs index dec4b4d..957d533 100644 --- a/crates/tinywasm/src/interpreter/simd/instructions.rs +++ b/crates/tinywasm/src/interpreter/simd/instructions.rs @@ -44,7 +44,7 @@ impl Value128 { pub fn v128_and(self, rhs: Self) -> Self { simd_impl! { wasm => { Self::from_wasm_v128(wasm::v128_and(self.to_wasm_v128(), rhs.to_wasm_v128())) } - generic => { (i128::from_le_bytes(self.0) & i128::from_le_bytes(rhs.0)).into() } + generic => { (i128::from(self) & i128::from(rhs)).into() } } } @@ -52,7 +52,7 @@ impl Value128 { pub fn v128_andnot(self, rhs: Self) -> Self { simd_impl! { wasm => { Self::from_wasm_v128(wasm::v128_andnot(self.to_wasm_v128(), rhs.to_wasm_v128())) } - generic => { (i128::from_le_bytes(self.0) & !i128::from_le_bytes(rhs.0)).into() } + generic => { (i128::from(self) & !i128::from(rhs)).into() } } } @@ -60,7 +60,7 @@ impl Value128 { pub fn v128_or(self, rhs: Self) -> Self { simd_impl! { wasm => { Self::from_wasm_v128(wasm::v128_or(self.to_wasm_v128(), rhs.to_wasm_v128())) } - generic => { (i128::from_le_bytes(self.0) | i128::from_le_bytes(rhs.0)).into() } + generic => { (i128::from(self) | i128::from(rhs)).into() } } } @@ -68,7 +68,7 @@ impl Value128 { pub fn v128_xor(self, rhs: Self) -> Self { simd_impl! { wasm => { Self::from_wasm_v128(wasm::v128_xor(self.to_wasm_v128(), rhs.to_wasm_v128())) } - generic => { (i128::from_le_bytes(self.0) ^ i128::from_le_bytes(rhs.0)).into() } + generic => { (i128::from(self) ^ i128::from(rhs)).into() } } } @@ -76,7 +76,7 @@ impl Value128 { pub fn v128_bitselect(v1: Self, v2: Self, c: Self) -> Self { simd_impl! { wasm => { Self::from_wasm_v128(wasm::v128_bitselect(v1.to_wasm_v128(), v2.to_wasm_v128(), c.to_wasm_v128())) } - generic => { ((i128::from_le_bytes(v1.0) & i128::from_le_bytes(c.0)) | (i128::from_le_bytes(v2.0) & !i128::from_le_bytes(c.0))).into() } + generic => { ((i128::from(v1) & i128::from(c)) | (i128::from(v2) & !i128::from(c))).into() } } } @@ -185,20 +185,20 @@ impl Value128 { #[doc(alias = "i8x16.relaxed_swizzle")] pub fn i8x16_relaxed_swizzle(self, s: Self) -> Self { - self.i8x16_swizzle(s) + simd_impl! { + wasm => { Self::from_wasm_v128(wasm::i8x16_relaxed_swizzle(self.to_wasm_v128(), s.to_wasm_v128())) } + generic => { self.i8x16_swizzle(s) } + } } #[doc(alias = "i8x16.shuffle")] pub fn i8x16_shuffle(a: Self, b: Self, idx: Self) -> Self { simd_impl! { x86 => { - let a_bytes = a.0; - let b_bytes = b.0; - let idx = idx.0; let mut mask_a = [0u8; 16]; let mut mask_b = [0u8; 16]; for i in 0..16 { - let j = idx[i] & 31; + let j = idx.0[i] & 31; mask_a[i] = if j < 16 { j } else { 0x80 }; mask_b[i] = if j < 16 { 0x80 } else { j & 0x0f }; } @@ -206,8 +206,8 @@ impl Value128 { // SAFETY: all inputs are valid 16-byte buffers, and `_mm_loadu/_mm_storeu` support unaligned accesses. #[allow(unsafe_code)] let out = unsafe { - let a_vec = x86::_mm_loadu_si128(a_bytes.as_ptr().cast::<x86::__m128i>()); - let b_vec = x86::_mm_loadu_si128(b_bytes.as_ptr().cast::<x86::__m128i>()); + let a_vec = x86::_mm_loadu_si128(a.0.as_ptr().cast::<x86::__m128i>()); + let b_vec = x86::_mm_loadu_si128(b.0.as_ptr().cast::<x86::__m128i>()); let mask_a_vec = x86::_mm_loadu_si128(mask_a.as_ptr().cast::<x86::__m128i>()); let mask_b_vec = x86::_mm_loadu_si128(mask_b.as_ptr().cast::<x86::__m128i>()); let a_part = x86::_mm_shuffle_epi8(a_vec, mask_a_vec); @@ -287,9 +287,7 @@ impl Value128 { pub fn i64x2_all_true(self) -> bool { self.0 .chunks_exact(8) - .map(|chunk| { - u64::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], chunk[5], chunk[6], chunk[7]]) - }) + .map(|c| u64::from_le_bytes([c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]])) .all(|x| x != 0) } @@ -349,14 +347,17 @@ impl Value128 { pub fn i8x16_shl(self, shift: u32) -> Self { simd_shift_left!(self, shift, i8, 16, as_i8x16, from_i8x16, 7) } + #[doc(alias = "i16x8.shl")] pub fn i16x8_shl(self, shift: u32) -> Self { simd_shift_left!(self, shift, i16, 8, as_i16x8, from_i16x8, 15) } + #[doc(alias = "i32x4.shl")] pub fn i32x4_shl(self, shift: u32) -> Self { simd_shift_left!(self, shift, i32, 4, as_i32x4, from_i32x4, 31) } + #[doc(alias = "i64x2.shl")] pub fn i64x2_shl(self, shift: u32) -> Self { simd_shift_left!(self, shift, i64, 2, as_i64x2, from_i64x2, 63) @@ -366,14 +367,17 @@ impl Value128 { pub fn i8x16_shr_s(self, shift: u32) -> Self { simd_shift_right!(self, shift, i8, 16, as_i8x16, from_i8x16, 7) } + #[doc(alias = "i16x8.shr_s")] pub fn i16x8_shr_s(self, shift: u32) -> Self { simd_shift_right!(self, shift, i16, 8, as_i16x8, from_i16x8, 15) } + #[doc(alias = "i32x4.shr_s")] pub fn i32x4_shr_s(self, shift: u32) -> Self { simd_shift_right!(self, shift, i32, 4, as_i32x4, from_i32x4, 31) } + #[doc(alias = "i64x2.shr_s")] pub fn i64x2_shr_s(self, shift: u32) -> Self { simd_shift_right!(self, shift, i64, 2, as_i64x2, from_i64x2, 63) @@ -383,14 +387,17 @@ impl Value128 { pub fn i8x16_shr_u(self, shift: u32) -> Self { simd_shift_right!(self, shift, u8, 16, as_u8x16, from_u8x16, 7) } + #[doc(alias = "i16x8.shr_u")] pub fn i16x8_shr_u(self, shift: u32) -> Self { simd_shift_right!(self, shift, u16, 8, as_u16x8, from_u16x8, 15) } + #[doc(alias = "i32x4.shr_u")] pub fn i32x4_shr_u(self, shift: u32) -> Self { simd_shift_right!(self, shift, u32, 4, as_u32x4, from_u32x4, 31) } + #[doc(alias = "i64x2.shr_u")] pub fn i64x2_shr_u(self, shift: u32) -> Self { simd_shift_right!(self, shift, u64, 2, as_u64x2, from_u64x2, 63) @@ -400,42 +407,52 @@ impl Value128 { pub fn i8x16_add(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i8x16_add, i8, 16, as_i8x16, from_i8x16, wrapping_add) } + #[doc(alias = "i16x8.add")] pub fn i16x8_add(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i16x8_add, i16, 8, as_i16x8, from_i16x8, wrapping_add) } + #[doc(alias = "i32x4.add")] pub fn i32x4_add(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i32x4_add, i32, 4, as_i32x4, from_i32x4, wrapping_add) } + #[doc(alias = "i64x2.add")] pub fn i64x2_add(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i64x2_add, i64, 2, as_i64x2, from_i64x2, wrapping_add) } + #[doc(alias = "i8x16.sub")] pub fn i8x16_sub(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i8x16_sub, i8, 16, as_i8x16, from_i8x16, wrapping_sub) } + #[doc(alias = "i16x8.sub")] pub fn i16x8_sub(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i16x8_sub, i16, 8, as_i16x8, from_i16x8, wrapping_sub) } + #[doc(alias = "i32x4.sub")] pub fn i32x4_sub(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i32x4_sub, i32, 4, as_i32x4, from_i32x4, wrapping_sub) } + #[doc(alias = "i64x2.sub")] pub fn i64x2_sub(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i64x2_sub, i64, 2, as_i64x2, from_i64x2, wrapping_sub) } + #[doc(alias = "i16x8.mul")] pub fn i16x8_mul(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i16x8_mul, i16, 8, as_i16x8, from_i16x8, wrapping_mul) } + #[doc(alias = "i32x4.mul")] pub fn i32x4_mul(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i32x4_mul, i32, 4, as_i32x4, from_i32x4, wrapping_mul) } + #[doc(alias = "i64x2.mul")] pub fn i64x2_mul(self, rhs: Self) -> Self { simd_wrapping_binop!(self, rhs, i64x2_mul, i64, 2, as_i64x2, from_i64x2, wrapping_mul) @@ -445,30 +462,37 @@ impl Value128 { pub fn i8x16_add_sat_s(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, i8x16_add_sat, i8, 16, as_i8x16, from_i8x16, saturating_add) } + #[doc(alias = "i16x8.add_sat_s")] pub fn i16x8_add_sat_s(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, i16x8_add_sat, i16, 8, as_i16x8, from_i16x8, saturating_add) } + #[doc(alias = "i8x16.add_sat_u")] pub fn i8x16_add_sat_u(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, u8x16_add_sat, u8, 16, as_u8x16, from_u8x16, saturating_add) } + #[doc(alias = "i16x8.add_sat_u")] pub fn i16x8_add_sat_u(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, u16x8_add_sat, u16, 8, as_u16x8, from_u16x8, saturating_add) } + #[doc(alias = "i8x16.sub_sat_s")] pub fn i8x16_sub_sat_s(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, i8x16_sub_sat, i8, 16, as_i8x16, from_i8x16, saturating_sub) } + #[doc(alias = "i16x8.sub_sat_s")] pub fn i16x8_sub_sat_s(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, i16x8_sub_sat, i16, 8, as_i16x8, from_i16x8, saturating_sub) } + #[doc(alias = "i8x16.sub_sat_u")] pub fn i8x16_sub_sat_u(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, u8x16_sub_sat, u8, 16, as_u8x16, from_u8x16, saturating_sub) } + #[doc(alias = "i16x8.sub_sat_u")] pub fn i16x8_sub_sat_u(self, rhs: Self) -> Self { simd_sat_binop!(self, rhs, u16x8_sub_sat, u16, 8, as_u16x8, from_u16x8, saturating_sub) @@ -478,6 +502,7 @@ impl Value128 { pub fn i8x16_avgr_u(self, rhs: Self) -> Self { simd_avgr_u!(self, rhs, u8x16_avgr, u8, u16, 16, as_u8x16, from_u8x16) } + #[doc(alias = "i16x8.avgr_u")] pub fn i16x8_avgr_u(self, rhs: Self) -> Self { simd_avgr_u!(self, rhs, u16x8_avgr, u16, u32, 8, as_u16x8, from_u16x8) @@ -579,46 +604,57 @@ impl Value128 { pub fn i16x8_extend_low_i8x16_s(self) -> Self { simd_extend_cast!(self, as_i8x16, from_i16x8, i16, 8, 0) } + #[doc(alias = "i16x8.extend_low_i8x16_u")] pub fn i16x8_extend_low_i8x16_u(self) -> Self { simd_extend_cast!(self, as_u8x16, from_u16x8, u16, 8, 0) } + #[doc(alias = "i16x8.extend_high_i8x16_s")] pub fn i16x8_extend_high_i8x16_s(self) -> Self { simd_extend_cast!(self, as_i8x16, from_i16x8, i16, 8, 8) } + #[doc(alias = "i16x8.extend_high_i8x16_u")] pub fn i16x8_extend_high_i8x16_u(self) -> Self { simd_extend_cast!(self, as_u8x16, from_u16x8, u16, 8, 8) } + #[doc(alias = "i32x4.extend_low_i16x8_s")] pub fn i32x4_extend_low_i16x8_s(self) -> Self { simd_extend_cast!(self, as_i16x8, from_i32x4, i32, 4, 0) } + #[doc(alias = "i32x4.extend_low_i16x8_u")] pub fn i32x4_extend_low_i16x8_u(self) -> Self { simd_extend_cast!(self, as_u16x8, from_u32x4, u32, 4, 0) } + #[doc(alias = "i32x4.extend_high_i16x8_s")] pub fn i32x4_extend_high_i16x8_s(self) -> Self { simd_extend_cast!(self, as_i16x8, from_i32x4, i32, 4, 4) } + #[doc(alias = "i32x4.extend_high_i16x8_u")] pub fn i32x4_extend_high_i16x8_u(self) -> Self { simd_extend_cast!(self, as_u16x8, from_u32x4, u32, 4, 4) } + #[doc(alias = "i64x2.extend_low_i32x4_s")] pub fn i64x2_extend_low_i32x4_s(self) -> Self { simd_extend_cast!(self, as_i32x4, from_i64x2, i64, 2, 0) } + #[doc(alias = "i64x2.extend_low_i32x4_u")] pub fn i64x2_extend_low_i32x4_u(self) -> Self { simd_extend_cast!(self, as_u32x4, from_u64x2, u64, 2, 0) } + #[doc(alias = "i64x2.extend_high_i32x4_s")] pub fn i64x2_extend_high_i32x4_s(self) -> Self { simd_extend_cast!(self, as_i32x4, from_i64x2, i64, 2, 2) } + #[doc(alias = "i64x2.extend_high_i32x4_u")] pub fn i64x2_extend_high_i32x4_u(self) -> Self { simd_extend_cast!(self, as_u32x4, from_u64x2, u64, 2, 2) @@ -628,46 +664,57 @@ impl Value128 { pub fn i16x8_extmul_low_i8x16_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i8x16, from_i16x8, i16, 8, 0) } + #[doc(alias = "i16x8.extmul_low_i8x16_u")] pub fn i16x8_extmul_low_i8x16_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u8x16, from_u16x8, u16, 8, 0) } + #[doc(alias = "i16x8.extmul_high_i8x16_s")] pub fn i16x8_extmul_high_i8x16_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i8x16, from_i16x8, i16, 8, 8) } + #[doc(alias = "i16x8.extmul_high_i8x16_u")] pub fn i16x8_extmul_high_i8x16_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u8x16, from_u16x8, u16, 8, 8) } + #[doc(alias = "i32x4.extmul_low_i16x8_s")] pub fn i32x4_extmul_low_i16x8_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i16x8, from_i32x4, i32, 4, 0) } + #[doc(alias = "i32x4.extmul_low_i16x8_u")] pub fn i32x4_extmul_low_i16x8_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u16x8, from_u32x4, u32, 4, 0) } + #[doc(alias = "i32x4.extmul_high_i16x8_s")] pub fn i32x4_extmul_high_i16x8_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i16x8, from_i32x4, i32, 4, 4) } + #[doc(alias = "i32x4.extmul_high_i16x8_u")] pub fn i32x4_extmul_high_i16x8_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u16x8, from_u32x4, u32, 4, 4) } + #[doc(alias = "i64x2.extmul_low_i32x4_s")] pub fn i64x2_extmul_low_i32x4_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i32x4, from_i64x2, i64, 2, 0) } + #[doc(alias = "i64x2.extmul_low_i32x4_u")] pub fn i64x2_extmul_low_i32x4_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u32x4, from_u64x2, u64, 2, 0) } + #[doc(alias = "i64x2.extmul_high_i32x4_s")] pub fn i64x2_extmul_high_i32x4_s(self, rhs: Self) -> Self { simd_extmul_signed!(self, rhs, as_i32x4, from_i64x2, i64, 2, 2) } + #[doc(alias = "i64x2.extmul_high_i32x4_u")] pub fn i64x2_extmul_high_i32x4_u(self, rhs: Self) -> Self { simd_extmul_unsigned!(self, rhs, as_u32x4, from_u64x2, u64, 2, 2) @@ -767,58 +814,72 @@ impl Value128 { pub fn i8x16_eq(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i8x16_eq, i8, 16, as_i8x16, from_i8x16, ==) } + #[doc(alias = "i16x8.eq")] pub fn i16x8_eq(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i16x8_eq, i16, 8, as_i16x8, from_i16x8, ==) } + #[doc(alias = "i32x4.eq")] pub fn i32x4_eq(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i32x4_eq, i32, 4, as_i32x4, from_i32x4, ==) } + #[doc(alias = "i64x2.eq")] pub fn i64x2_eq(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i64x2_eq, i64, 2, as_i64x2, from_i64x2, ==) } + #[doc(alias = "i8x16.ne")] pub fn i8x16_ne(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i8x16_ne, i8, 16, as_i8x16, from_i8x16, !=) } + #[doc(alias = "i16x8.ne")] pub fn i16x8_ne(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i16x8_ne, i16, 8, as_i16x8, from_i16x8, !=) } + #[doc(alias = "i32x4.ne")] pub fn i32x4_ne(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i32x4_ne, i32, 4, as_i32x4, from_i32x4, !=) } + #[doc(alias = "i64x2.ne")] pub fn i64x2_ne(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i64x2_ne, i64, 2, as_i64x2, from_i64x2, !=) } + #[doc(alias = "i8x16.lt_s")] pub fn i8x16_lt_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i8x16_lt, i8, 16, as_i8x16, from_i8x16, <) } + #[doc(alias = "i16x8.lt_s")] pub fn i16x8_lt_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i16x8_lt, i16, 8, as_i16x8, from_i16x8, <) } + #[doc(alias = "i32x4.lt_s")] pub fn i32x4_lt_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i32x4_lt, i32, 4, as_i32x4, from_i32x4, <) } + #[doc(alias = "i64x2.lt_s")] pub fn i64x2_lt_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i64x2_lt, i64, 2, as_i64x2, from_i64x2, <) } + #[doc(alias = "i8x16.lt_u")] pub fn i8x16_lt_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u8x16_lt, i8, 16, as_u8x16, from_i8x16, <) } + #[doc(alias = "i16x8.lt_u")] pub fn i16x8_lt_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u16x8_lt, i16, 8, as_u16x8, from_i16x8, <) } + #[doc(alias = "i32x4.lt_u")] pub fn i32x4_lt_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u32x4_lt, i32, 4, as_u32x4, from_i32x4, <) @@ -828,54 +889,67 @@ impl Value128 { pub fn i8x16_gt_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i8x16_lt_s) } + #[doc(alias = "i16x8.gt_s")] pub fn i16x8_gt_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i16x8_lt_s) } + #[doc(alias = "i32x4.gt_s")] pub fn i32x4_gt_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i32x4_lt_s) } + #[doc(alias = "i64x2.gt_s")] pub fn i64x2_gt_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i64x2_lt_s) } + #[doc(alias = "i8x16.gt_u")] pub fn i8x16_gt_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i8x16_lt_u) } + #[doc(alias = "i16x8.gt_u")] pub fn i16x8_gt_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i16x8_lt_u) } + #[doc(alias = "i32x4.gt_u")] pub fn i32x4_gt_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i32x4_lt_u) } + #[doc(alias = "i8x16.le_s")] pub fn i8x16_le_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i8x16_ge_s) } + #[doc(alias = "i16x8.le_s")] pub fn i16x8_le_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i16x8_ge_s) } + #[doc(alias = "i32x4.le_s")] pub fn i32x4_le_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i32x4_ge_s) } + #[doc(alias = "i64x2.le_s")] pub fn i64x2_le_s(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i64x2_ge_s) } + #[doc(alias = "i8x16.le_u")] pub fn i8x16_le_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i8x16_ge_u) } + #[doc(alias = "i16x8.le_u")] pub fn i16x8_le_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i16x8_ge_u) } + #[doc(alias = "i32x4.le_u")] pub fn i32x4_le_u(self, rhs: Self) -> Self { simd_cmp_delegate!(self, rhs, i32x4_ge_u) @@ -885,26 +959,32 @@ impl Value128 { pub fn i8x16_ge_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i8x16_ge, i8, 16, as_i8x16, from_i8x16, >=) } + #[doc(alias = "i16x8.ge_s")] pub fn i16x8_ge_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i16x8_ge, i16, 8, as_i16x8, from_i16x8, >=) } + #[doc(alias = "i32x4.ge_s")] pub fn i32x4_ge_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i32x4_ge, i32, 4, as_i32x4, from_i32x4, >=) } + #[doc(alias = "i64x2.ge_s")] pub fn i64x2_ge_s(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, i64x2_ge, i64, 2, as_i64x2, from_i64x2, >=) } + #[doc(alias = "i8x16.ge_u")] pub fn i8x16_ge_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u8x16_ge, i8, 16, as_u8x16, from_i8x16, >=) } + #[doc(alias = "i16x8.ge_u")] pub fn i16x8_ge_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u16x8_ge, i16, 8, as_u16x8, from_i16x8, >=) } + #[doc(alias = "i32x4.ge_u")] pub fn i32x4_ge_u(self, rhs: Self) -> Self { simd_cmp_mask!(self, rhs, u32x4_ge, i32, 4, as_u32x4, from_i32x4, >=) @@ -914,14 +994,17 @@ impl Value128 { pub fn i8x16_abs(self) -> Self { simd_abs_const!(self, i8, 16, as_i8x16, from_i8x16) } + #[doc(alias = "i16x8.abs")] pub fn i16x8_abs(self) -> Self { simd_abs_const!(self, i16, 8, as_i16x8, from_i16x8) } + #[doc(alias = "i32x4.abs")] pub fn i32x4_abs(self) -> Self { simd_abs_const!(self, i32, 4, as_i32x4, from_i32x4) } + #[doc(alias = "i64x2.abs")] pub fn i64x2_abs(self) -> Self { simd_abs_const!(self, i64, 2, as_i64x2, from_i64x2) @@ -931,14 +1014,17 @@ impl Value128 { pub fn i8x16_neg(self) -> Self { simd_neg!(self, i8x16_neg, i8, 16, as_i8x16, from_i8x16) } + #[doc(alias = "i16x8.neg")] pub fn i16x8_neg(self) -> Self { simd_neg!(self, i16x8_neg, i16, 8, as_i16x8, from_i16x8) } + #[doc(alias = "i32x4.neg")] pub fn i32x4_neg(self) -> Self { simd_neg!(self, i32x4_neg, i32, 4, as_i32x4, from_i32x4) } + #[doc(alias = "i64x2.neg")] pub fn i64x2_neg(self) -> Self { simd_neg!(self, i64x2_neg, i64, 2, as_i64x2, from_i64x2) @@ -948,46 +1034,57 @@ impl Value128 { pub fn i8x16_min_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i8x16_min, i8, 16, as_i8x16, from_i8x16, <) } + #[doc(alias = "i16x8.min_s")] pub fn i16x8_min_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i16x8_min, i16, 8, as_i16x8, from_i16x8, <) } + #[doc(alias = "i32x4.min_s")] pub fn i32x4_min_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i32x4_min, i32, 4, as_i32x4, from_i32x4, <) } + #[doc(alias = "i8x16.min_u")] pub fn i8x16_min_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u8x16_min, u8, 16, as_u8x16, from_u8x16, <) } + #[doc(alias = "i16x8.min_u")] pub fn i16x8_min_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u16x8_min, u16, 8, as_u16x8, from_u16x8, <) } + #[doc(alias = "i32x4.min_u")] pub fn i32x4_min_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u32x4_min, u32, 4, as_u32x4, from_u32x4, <) } + #[doc(alias = "i8x16.max_s")] pub fn i8x16_max_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i8x16_max, i8, 16, as_i8x16, from_i8x16, >) } + #[doc(alias = "i16x8.max_s")] pub fn i16x8_max_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i16x8_max, i16, 8, as_i16x8, from_i16x8, >) } + #[doc(alias = "i32x4.max_s")] pub fn i32x4_max_s(self, rhs: Self) -> Self { simd_minmax!(self, rhs, i32x4_max, i32, 4, as_i32x4, from_i32x4, >) } + #[doc(alias = "i8x16.max_u")] pub fn i8x16_max_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u8x16_max, u8, 16, as_u8x16, from_u8x16, >) } + #[doc(alias = "i16x8.max_u")] pub fn i16x8_max_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u16x8_max, u16, 8, as_u16x8, from_u16x8, >) } + #[doc(alias = "i32x4.max_u")] pub fn i32x4_max_u(self, rhs: Self) -> Self { simd_minmax!(self, rhs, u32x4_max, u32, 4, as_u32x4, from_u32x4, >) @@ -997,22 +1094,27 @@ impl Value128 { pub fn f32x4_eq(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i32, 4, as_f32x4, from_i32x4, ==) } + #[doc(alias = "f64x2.eq")] pub fn f64x2_eq(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i64, 2, as_f64x2, from_i64x2, ==) } + #[doc(alias = "f32x4.ne")] pub fn f32x4_ne(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i32, 4, as_f32x4, from_i32x4, !=) } + #[doc(alias = "f64x2.ne")] pub fn f64x2_ne(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i64, 2, as_f64x2, from_i64x2, !=) } + #[doc(alias = "f32x4.lt")] pub fn f32x4_lt(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i32, 4, as_f32x4, from_i32x4, <) } + #[doc(alias = "f64x2.lt")] pub fn f64x2_lt(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i64, 2, as_f64x2, from_i64x2, <) @@ -1032,14 +1134,17 @@ impl Value128 { pub fn f32x4_le(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i32, 4, as_f32x4, from_i32x4, <=) } + #[doc(alias = "f64x2.le")] pub fn f64x2_le(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i64, 2, as_f64x2, from_i64x2, <=) } + #[doc(alias = "f32x4.ge")] pub fn f32x4_ge(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i32, 4, as_f32x4, from_i32x4, >=) } + #[doc(alias = "f64x2.ge")] pub fn f64x2_ge(self, rhs: Self) -> Self { simd_cmp_mask_const!(self, rhs, i64, 2, as_f64x2, from_i64x2, >=) @@ -1049,54 +1154,67 @@ impl Value128 { pub fn f32x4_ceil(self) -> Self { simd_float_unary!(self, map_f32x4, |x| canonicalize_simd_f32_nan(x.ceil())) } + #[doc(alias = "f64x2.ceil")] pub fn f64x2_ceil(self) -> Self { simd_float_unary!(self, map_f64x2, |x| canonicalize_simd_f64_nan(x.ceil())) } + #[doc(alias = "f32x4.floor")] pub fn f32x4_floor(self) -> Self { simd_float_unary!(self, map_f32x4, |x| canonicalize_simd_f32_nan(x.floor())) } + #[doc(alias = "f64x2.floor")] pub fn f64x2_floor(self) -> Self { simd_float_unary!(self, map_f64x2, |x| canonicalize_simd_f64_nan(x.floor())) } + #[doc(alias = "f32x4.trunc")] pub fn f32x4_trunc(self) -> Self { simd_float_unary!(self, map_f32x4, |x| canonicalize_simd_f32_nan(x.trunc())) } + #[doc(alias = "f64x2.trunc")] pub fn f64x2_trunc(self) -> Self { simd_float_unary!(self, map_f64x2, |x| canonicalize_simd_f64_nan(x.trunc())) } + #[doc(alias = "f32x4.nearest")] pub fn f32x4_nearest(self) -> Self { simd_float_unary!(self, map_f32x4, |x| canonicalize_simd_f32_nan(TinywasmFloatExt::tw_nearest(x))) } + #[doc(alias = "f64x2.nearest")] pub fn f64x2_nearest(self) -> Self { simd_float_unary!(self, map_f64x2, |x| canonicalize_simd_f64_nan(TinywasmFloatExt::tw_nearest(x))) } + #[doc(alias = "f32x4.abs")] pub fn f32x4_abs(self) -> Self { simd_float_unary!(self, map_f32x4, f32::abs) } + #[doc(alias = "f64x2.abs")] pub fn f64x2_abs(self) -> Self { simd_float_unary!(self, map_f64x2, f64::abs) } + #[doc(alias = "f32x4.neg")] pub fn f32x4_neg(self) -> Self { simd_float_unary!(self, map_f32x4, |x| -x) } + #[doc(alias = "f64x2.neg")] pub fn f64x2_neg(self) -> Self { simd_float_unary!(self, map_f64x2, |x| -x) } + #[doc(alias = "f32x4.sqrt")] pub fn f32x4_sqrt(self) -> Self { simd_float_unary!(self, map_f32x4, |x| canonicalize_simd_f32_nan(x.sqrt())) } + #[doc(alias = "f64x2.sqrt")] pub fn f64x2_sqrt(self) -> Self { simd_float_unary!(self, map_f64x2, |x| canonicalize_simd_f64_nan(x.sqrt())) @@ -1106,62 +1224,77 @@ impl Value128 { pub fn f32x4_add(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| canonicalize_simd_f32_nan(a + b)) } + #[doc(alias = "f64x2.add")] pub fn f64x2_add(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| canonicalize_simd_f64_nan(a + b)) } + #[doc(alias = "f32x4.sub")] pub fn f32x4_sub(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| canonicalize_simd_f32_nan(a - b)) } + #[doc(alias = "f64x2.sub")] pub fn f64x2_sub(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| canonicalize_simd_f64_nan(a - b)) } + #[doc(alias = "f32x4.mul")] pub fn f32x4_mul(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| canonicalize_simd_f32_nan(a * b)) } + #[doc(alias = "f64x2.mul")] pub fn f64x2_mul(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| canonicalize_simd_f64_nan(a * b)) } + #[doc(alias = "f32x4.div")] pub fn f32x4_div(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| canonicalize_simd_f32_nan(a / b)) } + #[doc(alias = "f64x2.div")] pub fn f64x2_div(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| canonicalize_simd_f64_nan(a / b)) } + #[doc(alias = "f32x4.min")] pub fn f32x4_min(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, TinywasmFloatExt::tw_minimum) } + #[doc(alias = "f64x2.min")] pub fn f64x2_min(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, TinywasmFloatExt::tw_minimum) } + #[doc(alias = "f32x4.max")] pub fn f32x4_max(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, TinywasmFloatExt::tw_maximum) } + #[doc(alias = "f64x2.max")] pub fn f64x2_max(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, TinywasmFloatExt::tw_maximum) } + #[doc(alias = "f32x4.pmin")] pub fn f32x4_pmin(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| if b < a { b } else { a }) } + #[doc(alias = "f64x2.pmin")] pub fn f64x2_pmin(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| if b < a { b } else { a }) } + #[doc(alias = "f32x4.pmax")] pub fn f32x4_pmax(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f32x4, |a, b| if b > a { b } else { a }) } + #[doc(alias = "f64x2.pmax")] pub fn f64x2_pmax(self, rhs: Self) -> Self { simd_float_binary!(self, rhs, zip_f64x2, |a, b| if b > a { b } else { a }) @@ -1329,17 +1462,13 @@ impl Value128 { #[doc(alias = "i8x16.extract_lane_s")] pub fn extract_lane_i8(self, lane: u8) -> i8 { debug_assert!(lane < 16); - let lane = lane as usize; - let bytes = self.0; - bytes[lane] as i8 + self.0[lane as usize] as i8 } #[doc(alias = "i8x16.extract_lane_u")] pub fn extract_lane_u8(self, lane: u8) -> u8 { debug_assert!(lane < 16); - let lane = lane as usize; - let bytes = self.0; - bytes[lane] + self.0[lane as usize] } #[doc(alias = "i16x8.extract_lane_s")] diff --git a/crates/tinywasm/src/interpreter/simd/macros.rs b/crates/tinywasm/src/interpreter/simd/macros.rs index 91fdbb6..98ac1c7 100644 --- a/crates/tinywasm/src/interpreter/simd/macros.rs +++ b/crates/tinywasm/src/interpreter/simd/macros.rs @@ -1,49 +1,35 @@ #![allow(unused_macros)] +macro_rules! target_simd_x86 { + () => { + all( + feature = "simd-x86", + target_arch = "x86_64", + target_feature = "sse4.2", + target_feature = "avx", + target_feature = "avx2", + target_feature = "bmi1", + target_feature = "bmi2", + target_feature = "fma", + target_feature = "lzcnt", + target_feature = "movbe", + target_feature = "popcnt", + ) + }; +} + macro_rules! simd_impl { ($(wasm => $wasm:block)? $(x86 => $x86:block)? generic => $generic:block) => { cfg_select! { - any(target_arch = "wasm32", target_arch = "wasm64") => { - simd_impl!(@pick_wasm $( $wasm )? ; $generic) - }, - - all( - feature = "simd-x86", - target_arch = "x86_64", - target_feature = "sse4.2", - target_feature = "avx", - target_feature = "avx2", - target_feature = "bmi1", - target_feature = "bmi2", - target_feature = "fma", - target_feature = "lzcnt", - target_feature = "movbe", - target_feature = "popcnt" - ) => { - simd_impl!(@pick_x86 $( $x86 )? ; $generic) - }, - - _ => { - $generic - } + any(target_arch = "wasm32", target_arch = "wasm64") => { simd_impl!(@pick_wasm $( $wasm )? ; $generic) }, + all(feature = "simd-x86", target_arch = "x86_64", target_feature = "sse4.2", target_feature = "avx", target_feature = "avx2", target_feature = "bmi1", target_feature = "bmi2", target_feature = "fma", target_feature = "lzcnt", target_feature = "movbe", target_feature = "popcnt") => { simd_impl!(@pick_x86 $( $x86 )? ; $generic) }, + _ => { $generic } } }; - - (@pick_wasm $wasm:block ; $generic:block) => { - $wasm - }; - - (@pick_wasm ; $generic:block) => { - $generic - }; - - (@pick_x86 $x86:block ; $generic:block) => { - $x86 - }; - - (@pick_x86 ; $generic:block) => { - $generic - }; + (@pick_wasm $wasm:block ; $generic:block) => { $wasm }; + (@pick_wasm ; $generic:block) => { $generic }; + (@pick_x86 $x86:block ; $generic:block) => { $x86 }; + (@pick_x86 ; $generic:block) => { $generic }; } macro_rules! simd_wrapping_binop_generic { diff --git a/crates/tinywasm/src/interpreter/simd/mod.rs b/crates/tinywasm/src/interpreter/simd/mod.rs index 55e342a..e6784d7 100644 --- a/crates/tinywasm/src/interpreter/simd/mod.rs +++ b/crates/tinywasm/src/interpreter/simd/mod.rs @@ -12,8 +12,6 @@ use core::arch::wasm32 as wasm; #[cfg(target_arch = "wasm64")] use core::arch::wasm64 as wasm; -use crate::MemValue; - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] /// A 128-bit SIMD value pub struct Value128(pub(super) [u8; 16]); @@ -24,21 +22,16 @@ impl From<[u8; 16]> for Value128 { } } -impl MemValue<16> for Value128 { +impl Value128 { #[inline(always)] - fn from_mem_bytes(bytes: [u8; 16]) -> Self { + pub fn from_le_bytes(bytes: [u8; 16]) -> Self { Self(bytes) } #[inline(always)] - fn to_mem_bytes(self) -> [u8; 16] { + pub fn to_le_bytes(self) -> [u8; 16] { self.0 } - - #[inline(always)] - fn load(mem: &dyn crate::LinearMemory, base: u64, offset: u64) -> core::result::Result<Self, crate::Trap> { - Ok(Self(mem.read_128(base, offset)?)) - } } impl From<Value128> for i128 { @@ -55,6 +48,19 @@ impl From<i128> for Value128 { #[cfg_attr(any(target_arch = "wasm32", target_arch = "wasm64"), allow(unreachable_code))] impl Value128 { + impl_lane_accessors! { + as_i8x16 => from_i8x16: i8, 16, 1; + as_u8x16 => from_u8x16: u8, 16, 1; + as_i16x8 => from_i16x8: i16, 8, 2; + as_u16x8 => from_u16x8: u16, 8, 2; + as_i32x4 => pub from_i32x4: i32, 4, 4; + as_u32x4 => from_u32x4: u32, 4, 4; + as_f32x4 => from_f32x4: f32, 4, 4; + as_i64x2 => pub from_i64x2: i64, 2, 8; + as_u64x2 => from_u64x2: u64, 2, 8; + as_f64x2 => from_f64x2: f64, 2, 8; + } + #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))] #[inline(always)] fn to_wasm_v128(self) -> wasm::v128 { @@ -71,19 +77,6 @@ impl Value128 { Self([ wasm::u8x16_extract_lane::<0>(value), wasm::u8x16_extract_lane::<1>(value), wasm::u8x16_extract_lane::<2>(value), wasm::u8x16_extract_lane::<3>(value), wasm::u8x16_extract_lane::<4>(value), wasm::u8x16_extract_lane::<5>(value), wasm::u8x16_extract_lane::<6>(value), wasm::u8x16_extract_lane::<7>(value), wasm::u8x16_extract_lane::<8>(value), wasm::u8x16_extract_lane::<9>(value), wasm::u8x16_extract_lane::<10>(value), wasm::u8x16_extract_lane::<11>(value), wasm::u8x16_extract_lane::<12>(value), wasm::u8x16_extract_lane::<13>(value), wasm::u8x16_extract_lane::<14>(value), wasm::u8x16_extract_lane::<15>(value)]) } - impl_lane_accessors! { - as_i8x16 => from_i8x16: i8, 16, 1; - as_u8x16 => from_u8x16: u8, 16, 1; - as_i16x8 => from_i16x8: i16, 8, 2; - as_u16x8 => from_u16x8: u16, 8, 2; - as_i32x4 => pub from_i32x4: i32, 4, 4; - as_u32x4 => from_u32x4: u32, 4, 4; - as_f32x4 => from_f32x4: f32, 4, 4; - as_i64x2 => pub from_i64x2: i64, 2, 8; - as_u64x2 => from_u64x2: u64, 2, 8; - as_f64x2 => from_f64x2: f64, 2, 8; - } - #[inline] fn map_f32x4(self, mut op: impl FnMut(f32) -> f32) -> Self { let bytes = self.0; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 9be804a..014f7a3 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -3,11 +3,9 @@ use core::hint::cold_path; use tinywasm_types::{ExternRef, FuncRef, ValueCounts, WasmType, WasmValue}; use super::StackBase; -use crate::{ - Result, Trap, - engine::{Config, StackConfig}, - interpreter::*, -}; +use crate::engine::{Config, StackConfig}; +use crate::interpreter::*; +use crate::{Result, Trap}; #[cfg_attr(feature = "debug", derive(Debug))] pub(crate) struct ValueStack { diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index ddda317..a880574 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -1,8 +1,6 @@ -use crate::{Result, interpreter::simd::Value128}; - use super::stack::{CallFrame, ValueStack}; -use tinywasm_types::LocalAddr; -use tinywasm_types::{ExternRef, FuncRef, WasmType, WasmValue}; +use crate::{Result, interpreter::simd::Value128}; +use tinywasm_types::{ExternRef, FuncRef, LocalAddr, WasmType, WasmValue}; pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index 8541062..51e0cee 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -1,8 +1,9 @@ use core::hint::cold_path; +use alloc::ffi::CString; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; -use alloc::{ffi::CString, format}; use crate::store::{GlobalInstance, TableElement, TableInstance}; use crate::{Error, MemoryInstance, Result, Store, Trap}; diff --git a/crates/tinywasm/src/store/memory/instance.rs b/crates/tinywasm/src/store/memory/instance.rs index 19cfd3f..9a3d462 100644 --- a/crates/tinywasm/src/store/memory/instance.rs +++ b/crates/tinywasm/src/store/memory/instance.rs @@ -1,14 +1,9 @@ use alloc::format; -use tinywasm_types::MemoryArch; -use tinywasm_types::MemoryType; +use tinywasm_types::{MemoryArch, MemoryType}; -use crate::Error; -use crate::MemoryBackend; -use crate::Result; -use crate::Trap; +use crate::{Error, MemoryBackend, Result, Trap}; -use super::MemoryStorage; -use super::memory_oob; +use super::{MemoryStorage, memory_oob}; use core::hint::cold_path; /// A WebAssembly Memory Instance diff --git a/crates/tinywasm/src/store/memory/mod.rs b/crates/tinywasm/src/store/memory/mod.rs index 2e58939..33311ea 100644 --- a/crates/tinywasm/src/store/memory/mod.rs +++ b/crates/tinywasm/src/store/memory/mod.rs @@ -1,14 +1,12 @@ -use alloc::boxed::Box; -use alloc::format; -use alloc::sync::Arc; -use alloc::vec; -use alloc::vec::Vec; +use alloc::{boxed::Box, format, sync::Arc}; +use alloc::{vec, vec::Vec}; +use core::cmp::min; use core::hint::cold_path; -use core::ops::DerefMut; -use core::{cmp::min, ops::Deref}; +use core::ops::{Deref, DerefMut}; use tinywasm_types::MemoryType; +use crate::interpreter::Value128; use crate::{Error, Result}; mod instance; @@ -443,7 +441,7 @@ impl MemValue<1> for i8 { impl_mem_traits!( u16, 2, read_16, i16, 2, read_16, u32, 4, read_32, i32, 4, read_32, f32, 4, read_32, u64, 8, read_64, i64, 8, - read_64, f64, 8, read_64, + read_64, f64, 8, read_64, Value128, 16, read_128 ); fn memory_oob(offset: usize, len: usize, max: usize) -> crate::Trap { diff --git a/crates/tinywasm/tests/host_func_signature_check.rs b/crates/tinywasm/tests/host_func_signature_check.rs index ef8b2a1..b0e50b2 100644 --- a/crates/tinywasm/tests/host_func_signature_check.rs +++ b/crates/tinywasm/tests/host_func_signature_check.rs @@ -1,9 +1,7 @@ use eyre::Result; use std::fmt::Write; -use tinywasm::{ - FuncContext, HostFunction, Imports, Module, ModuleInstance, Store, - types::{FuncType, WasmType, WasmValue}, -}; +use tinywasm::types::{FuncType, WasmType, WasmValue}; +use tinywasm::{FuncContext, HostFunction, Imports, Module, ModuleInstance, Store}; use tinywasm_types::ExternRef; const VAL_LISTS: &[&[WasmValue]] = &[ diff --git a/crates/tinywasm/tests/resume_execution.rs b/crates/tinywasm/tests/resume_execution.rs index 82e8a11..060cefb 100644 --- a/crates/tinywasm/tests/resume_execution.rs +++ b/crates/tinywasm/tests/resume_execution.rs @@ -1,7 +1,6 @@ use eyre::Result; -use tinywasm::ModuleInstance; use tinywasm::engine::{Config, FuelPolicy}; -use tinywasm::{ExecProgress, types::WasmValue}; +use tinywasm::{ExecProgress, ModuleInstance, types::WasmValue}; #[cfg(feature = "std")] use std::time::Duration; diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 8057518..e576027 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -76,6 +76,7 @@ impl From<ModuleInner> for Module { impl Deref for Module { type Target = ModuleInner; + fn deref(&self) -> &ModuleInner { &self.0 } |
