summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-05-25 22:49:33 +0200
committerHenry Gressmann <mail@henrygressmann.de>2024-05-25 22:49:33 +0200
commitc414c174fc00bbd2058663c8b6fcd3f6986fa41e (patch)
tree49a101dbb94975021e35dab1fae47b5350ac672a /crates
parent37e01524940259c4d3b82b8cd2facff67487440e (diff)
chore: improve simd
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
-rw-r--r--crates/parser/src/conversion.rs2
-rw-r--r--crates/parser/src/visit.rs4
-rw-r--r--crates/tinywasm/Cargo.toml3
-rw-r--r--crates/tinywasm/src/error.rs2
-rw-r--r--crates/tinywasm/src/lib.rs2
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs64
-rw-r--r--crates/tinywasm/src/runtime/mod.rs2
-rw-r--r--crates/tinywasm/src/runtime/raw_simd.rs16
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs4
-rw-r--r--crates/tinywasm/src/runtime/stack/mod.rs3
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs13
-rw-r--r--crates/tinywasm/src/std.rs2
-rw-r--r--crates/types/src/value.rs5
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,