diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2024-05-25 22:49:33 +0200 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2024-05-25 22:49:33 +0200 |
| commit | c414c174fc00bbd2058663c8b6fcd3f6986fa41e (patch) | |
| tree | 49a101dbb94975021e35dab1fae47b5350ac672a /crates | |
| parent | 37e01524940259c4d3b82b8cd2facff67487440e (diff) | |
chore: improve simd
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/parser/src/conversion.rs | 2 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 4 | ||||
| -rw-r--r-- | crates/tinywasm/Cargo.toml | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/error.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/interpreter/mod.rs | 64 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/mod.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/raw_simd.rs | 16 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/call_stack.rs | 4 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/mod.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/value_stack.rs | 13 | ||||
| -rw-r--r-- | crates/tinywasm/src/std.rs | 2 | ||||
| -rw-r--r-- | crates/types/src/value.rs | 5 |
13 files changed, 91 insertions, 31 deletions
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 001d7cc..bc082f0 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -225,8 +225,8 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType { wasmparser::ValType::I64 => ValType::I64, wasmparser::ValType::F32 => ValType::F32, wasmparser::ValType::F64 => ValType::F64, + wasmparser::ValType::V128 => ValType::V128, wasmparser::ValType::Ref(r) => convert_reftype(r), - wasmparser::ValType::V128 => unimplemented!("128-bit values are not supported yet"), } } diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index a506ecb..6002996 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -86,8 +86,8 @@ macro_rules! define_mem_operands { ($($name:ident, $instr:ident),*) => { $( #[inline(always)] - fn $name(&mut self, mem_arg: wasmparser::MemArg) -> Self::Output { - let arg = convert_memarg(mem_arg); + fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { + let arg = convert_memarg(memarg); self.instructions.push(Instruction::$instr { offset: arg.offset, mem_addr: arg.mem_addr, diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 0dfde7b..f5aaf50 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -28,12 +28,13 @@ serde={version="1.0", features=["derive"]} pretty_env_logger="0.5" [features] -default=["std", "parser", "logging", "archive"] +default=["std", "parser", "logging", "archive", "simd", "nightly"] logging=["_log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] parser=["tinywasm-parser"] archive=["tinywasm-types/archive"] simd=[] +nightly=[] [[test]] name="test-mvp" diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 85ffdf6..0c698fa 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -237,7 +237,7 @@ impl Display for Trap { } } -#[cfg(any(feature = "std", all(not(feature = "std"), nightly)))] +#[cfg(any(feature = "std", all(not(feature = "std"), feature = "nightly")))] impl crate::std::error::Error for Error {} #[cfg(feature = "parser")] diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 24cf56a..9c48ee0 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -5,7 +5,7 @@ ))] #![allow(unexpected_cfgs, clippy::reserve_after_initialization)] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] -#![cfg_attr(nightly, feature(error_in_core, portable_simd))] +#![cfg_attr(feature = "nightly", feature(error_in_core, portable_simd))] #![forbid(unsafe_code)] //! A tiny WebAssembly Runtime written in Rust diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs index d1bad62..c0d8f80 100644 --- a/crates/tinywasm/src/runtime/interpreter/mod.rs +++ b/crates/tinywasm/src/runtime/interpreter/mod.rs @@ -747,22 +747,56 @@ impl<'store, 'stack> Executor<'store, 'stack> { #[inline(always)] fn enter_block(&mut self, instr_ptr: usize, end_instr_offset: u32, ty: BlockType, args: BlockArgs) { - let (params, results) = match args { - BlockArgs::Empty => (0, 0), - BlockArgs::Type(_) => (0, 1), - BlockArgs::FuncType(t) => { - let ty = self.module.func_ty(t); - (ty.params.len() as u8, ty.results.len() as u8) - } + #[cfg(not(feature = "simd"))] + { + let (params, results) = match args { + BlockArgs::Empty => (0, 0), + BlockArgs::Type(_) => (0, 1), + BlockArgs::FuncType(t) => { + let ty = self.module.func_ty(t); + (ty.params.len() as u8, ty.results.len() as u8) + } + }; + + self.stack.blocks.push(BlockFrame { + instr_ptr, + end_instr_offset, + stack_ptr: self.stack.values.len() as u32 - params as u32, + results, + params, + ty, + }); }; - self.stack.blocks.push(BlockFrame { - instr_ptr, - end_instr_offset, - stack_ptr: self.stack.values.len() as u32 - params as u32, - results, - params, - ty, - }); + #[cfg(feature = "simd")] + { + let (params, results, simd_params, simd_results) = match args { + BlockArgs::Empty => (0, 0, 0, 0), + BlockArgs::Type(t) => match t { + ValType::V128 => (0, 0, 0, 1), + _ => (0, 1, 0, 0), + }, + BlockArgs::FuncType(t) => { + let ty = self.module.func_ty(t); + let simd_params = ty.params.iter().filter(|t| t.is_simd()).count() as u8; + let params = ty.params.len() as u8 - simd_params; + let simd_results = ty.results.iter().filter(|t| t.is_simd()).count() as u8; + let results = ty.results.len() as u8 - simd_results; + (params, results, simd_params, simd_results) + } + }; + + self.stack.blocks.push(BlockFrame { + instr_ptr, + end_instr_offset, + stack_ptr: self.stack.values.len() as u32 - params as u32, + simd_stack_ptr: self.stack.values.simd_len() as u32 - simd_params as u32, + results, + simd_params, + simd_results, + params, + ty, + }); + }; } } diff --git a/crates/tinywasm/src/runtime/mod.rs b/crates/tinywasm/src/runtime/mod.rs index d4572dd..6c8a553 100644 --- a/crates/tinywasm/src/runtime/mod.rs +++ b/crates/tinywasm/src/runtime/mod.rs @@ -3,7 +3,7 @@ mod stack; mod raw; -#[cfg(all(not(nightly), feature = "simd"))] +#[cfg(all(not(feature = "nightly"), feature = "simd"))] compile_error!("`simd` feature requires nightly"); #[cfg(feature = "simd")] diff --git a/crates/tinywasm/src/runtime/raw_simd.rs b/crates/tinywasm/src/runtime/raw_simd.rs index 46cb0c5..ba7dd62 100644 --- a/crates/tinywasm/src/runtime/raw_simd.rs +++ b/crates/tinywasm/src/runtime/raw_simd.rs @@ -1,13 +1,27 @@ +use core::{fmt::Debug, simd::Simd}; + /// A large raw wasm value, used for 128-bit values. /// /// This is the internal representation of vector values. /// /// See [`WasmValue`] for the public representation. #[derive(Clone, Copy, Default, PartialEq, Eq)] -pub struct RawSimdWasmValue([u8; 16]); +pub struct RawSimdWasmValue(Simd<u8, 16>); // wasm has up to 16 8 bit lanes impl Debug for RawSimdWasmValue { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "LargeRawWasmValue({})", 0) } } + +impl From<u128> for RawSimdWasmValue { + fn from(value: u128) -> Self { + Self(value.to_le_bytes().into()) + } +} + +impl From<RawSimdWasmValue> for u128 { + fn from(value: RawSimdWasmValue) -> Self { + u128::from_le_bytes(value.0.into()) + } +} diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index b3a78ed..b7360a0 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -84,7 +84,7 @@ impl CallFrame { self.instr_ptr = break_to.instr_ptr; // We also want to push the params to the stack - values.break_to_params(&break_to); + values.break_to_params(break_to); // check if we're breaking to the loop if break_to_relative != 0 { @@ -97,7 +97,7 @@ impl CallFrame { BlockType::Block | BlockType::If | BlockType::Else => { // this is a block, so we want to jump to the next instruction after the block ends // We also want to push the block's results to the stack - values.break_to_results(&break_to); + values.break_to_results(break_to); // (the inst_ptr will be incremented by 1 before the next instruction is executed) self.instr_ptr = break_to.instr_ptr + break_to.end_instr_offset as usize; diff --git a/crates/tinywasm/src/runtime/stack/mod.rs b/crates/tinywasm/src/runtime/stack/mod.rs index 3ef5348..052a67c 100644 --- a/crates/tinywasm/src/runtime/stack/mod.rs +++ b/crates/tinywasm/src/runtime/stack/mod.rs @@ -2,9 +2,6 @@ mod block_stack; mod call_stack; mod value_stack; -#[cfg(nightly)] -mod simd_value_stack; - pub(crate) use block_stack::{BlockFrame, BlockStack, BlockType}; pub(crate) use call_stack::{CallFrame, CallStack}; pub(crate) use value_stack::ValueStack; diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs index 5794268..c4c4050 100644 --- a/crates/tinywasm/src/runtime/stack/value_stack.rs +++ b/crates/tinywasm/src/runtime/stack/value_stack.rs @@ -9,6 +9,9 @@ pub(crate) const MIN_VALUE_STACK_SIZE: usize = 1024 * 128; #[cfg(feature = "simd")] pub(crate) const MIN_SIMD_VALUE_STACK_SIZE: usize = 1024 * 32; +#[cfg(feature = "simd")] +use crate::runtime::raw_simd::RawSimdWasmValue; + #[derive(Debug)] pub(crate) struct ValueStack { stack: Vec<RawWasmValue>, @@ -37,7 +40,7 @@ impl ValueStack { #[cfg(feature = "simd")] { values.iter().for_each(|v| match v { - WasmValue::V128(v) => self.simd_stack.push(*v), + WasmValue::V128(v) => self.simd_stack.push(RawSimdWasmValue::from(*v)), v => self.stack.push(RawWasmValue::from(*v)), }); } @@ -74,6 +77,12 @@ impl ValueStack { self.stack.len() } + #[cfg(feature = "simd")] + #[inline(always)] + pub(crate) fn simd_len(&self) -> usize { + self.simd_stack.len() + } + #[inline] pub(crate) fn truncate_keep(&mut self, n: u32, end_keep: u32) { truncate_keep(&mut self.stack, n, end_keep); @@ -138,7 +147,7 @@ impl ValueStack { let mut values = Vec::with_capacity(types.len()); for ty in types { match ty { - ValType::V128 => values.push(WasmValue::V128(self.simd_stack.pop().unwrap())), + ValType::V128 => values.push(WasmValue::V128(self.simd_stack.pop().unwrap().into())), ty => values.push(self.pop()?.attach_type(*ty)), } } diff --git a/crates/tinywasm/src/std.rs b/crates/tinywasm/src/std.rs index b77675b..f1e97a4 100644 --- a/crates/tinywasm/src/std.rs +++ b/crates/tinywasm/src/std.rs @@ -13,6 +13,6 @@ pub(crate) mod error { #[cfg(feature = "std")] pub(crate) use std::error::Error; - #[cfg(all(not(feature = "std"), nightly))] + #[cfg(all(not(feature = "std"), feature = "nightly"))] pub(crate) use core::error::Error; } diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 2248c17..6c422d0 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -142,6 +142,11 @@ impl ValType { WasmValue::default_for(*self) } + #[inline] + pub fn is_simd(&self) -> bool { + matches!(self, ValType::V128) + } + pub(crate) fn to_byte(self) -> u8 { match self { ValType::I32 => 0x7F, |
