Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit c414c17

Browse files
chore: improve simd
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent 37e0152 commit c414c17

File tree

13 files changed

+91
-31
lines changed

13 files changed

+91
-31
lines changed

crates/parser/src/conversion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType {
225225
wasmparser::ValType::I64 => ValType::I64,
226226
wasmparser::ValType::F32 => ValType::F32,
227227
wasmparser::ValType::F64 => ValType::F64,
228+
wasmparser::ValType::V128 => ValType::V128,
228229
wasmparser::ValType::Ref(r) => convert_reftype(r),
229-
wasmparser::ValType::V128 => unimplemented!("128-bit values are not supported yet"),
230230
}
231231
}
232232

crates/parser/src/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ macro_rules! define_mem_operands {
8686
($($name:ident, $instr:ident),*) => {
8787
$(
8888
#[inline(always)]
89-
fn $name(&mut self, mem_arg: wasmparser::MemArg) -> Self::Output {
90-
let arg = convert_memarg(mem_arg);
89+
fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output {
90+
let arg = convert_memarg(memarg);
9191
self.instructions.push(Instruction::$instr {
9292
offset: arg.offset,
9393
mem_addr: arg.mem_addr,

crates/tinywasm/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ serde={version="1.0", features=["derive"]}
2828
pretty_env_logger="0.5"
2929

3030
[features]
31-
default=["std", "parser", "logging", "archive"]
31+
default=["std", "parser", "logging", "archive", "simd", "nightly"]
3232
logging=["_log", "tinywasm-parser?/logging", "tinywasm-types/logging"]
3333
std=["tinywasm-parser?/std", "tinywasm-types/std"]
3434
parser=["tinywasm-parser"]
3535
archive=["tinywasm-types/archive"]
3636
simd=[]
37+
nightly=[]
3738

3839
[[test]]
3940
name="test-mvp"

crates/tinywasm/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl Display for Trap {
237237
}
238238
}
239239

240-
#[cfg(any(feature = "std", all(not(feature = "std"), nightly)))]
240+
#[cfg(any(feature = "std", all(not(feature = "std"), feature = "nightly")))]
241241
impl crate::std::error::Error for Error {}
242242

243243
#[cfg(feature = "parser")]

crates/tinywasm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
))]
66
#![allow(unexpected_cfgs, clippy::reserve_after_initialization)]
77
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
8-
#![cfg_attr(nightly, feature(error_in_core, portable_simd))]
8+
#![cfg_attr(feature = "nightly", feature(error_in_core, portable_simd))]
99
#![forbid(unsafe_code)]
1010

1111
//! A tiny WebAssembly Runtime written in Rust

crates/tinywasm/src/runtime/interpreter/mod.rs

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -747,22 +747,56 @@ impl<'store, 'stack> Executor<'store, 'stack> {
747747

748748
#[inline(always)]
749749
fn enter_block(&mut self, instr_ptr: usize, end_instr_offset: u32, ty: BlockType, args: BlockArgs) {
750-
let (params, results) = match args {
751-
BlockArgs::Empty => (0, 0),
752-
BlockArgs::Type(_) => (0, 1),
753-
BlockArgs::FuncType(t) => {
754-
let ty = self.module.func_ty(t);
755-
(ty.params.len() as u8, ty.results.len() as u8)
756-
}
750+
#[cfg(not(feature = "simd"))]
751+
{
752+
let (params, results) = match args {
753+
BlockArgs::Empty => (0, 0),
754+
BlockArgs::Type(_) => (0, 1),
755+
BlockArgs::FuncType(t) => {
756+
let ty = self.module.func_ty(t);
757+
(ty.params.len() as u8, ty.results.len() as u8)
758+
}
759+
};
760+
761+
self.stack.blocks.push(BlockFrame {
762+
instr_ptr,
763+
end_instr_offset,
764+
stack_ptr: self.stack.values.len() as u32 - params as u32,
765+
results,
766+
params,
767+
ty,
768+
});
757769
};
758770

759-
self.stack.blocks.push(BlockFrame {
760-
instr_ptr,
761-
end_instr_offset,
762-
stack_ptr: self.stack.values.len() as u32 - params as u32,
763-
results,
764-
params,
765-
ty,
766-
});
771+
#[cfg(feature = "simd")]
772+
{
773+
let (params, results, simd_params, simd_results) = match args {
774+
BlockArgs::Empty => (0, 0, 0, 0),
775+
BlockArgs::Type(t) => match t {
776+
ValType::V128 => (0, 0, 0, 1),
777+
_ => (0, 1, 0, 0),
778+
},
779+
BlockArgs::FuncType(t) => {
780+
let ty = self.module.func_ty(t);
781+
let simd_params = ty.params.iter().filter(|t| t.is_simd()).count() as u8;
782+
let params = ty.params.len() as u8 - simd_params;
783+
let simd_results = ty.results.iter().filter(|t| t.is_simd()).count() as u8;
784+
let results = ty.results.len() as u8 - simd_results;
785+
(params, results, simd_params, simd_results)
786+
}
787+
};
788+
789+
self.stack.blocks.push(BlockFrame {
790+
instr_ptr,
791+
end_instr_offset,
792+
stack_ptr: self.stack.values.len() as u32 - params as u32,
793+
simd_stack_ptr: self.stack.values.simd_len() as u32 - simd_params as u32,
794+
results,
795+
simd_params,
796+
simd_results,
797+
params,
798+
ty,
799+
});
800+
};
767801
}
768802
}

crates/tinywasm/src/runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod stack;
33

44
mod raw;
55

6-
#[cfg(all(not(nightly), feature = "simd"))]
6+
#[cfg(all(not(feature = "nightly"), feature = "simd"))]
77
compile_error!("`simd` feature requires nightly");
88

99
#[cfg(feature = "simd")]
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1+
use core::{fmt::Debug, simd::Simd};
2+
13
/// A large raw wasm value, used for 128-bit values.
24
///
35
/// This is the internal representation of vector values.
46
///
57
/// See [`WasmValue`] for the public representation.
68
#[derive(Clone, Copy, Default, PartialEq, Eq)]
7-
pub struct RawSimdWasmValue([u8; 16]);
9+
pub struct RawSimdWasmValue(Simd<u8, 16>); // wasm has up to 16 8 bit lanes
810

911
impl Debug for RawSimdWasmValue {
1012
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1113
write!(f, "LargeRawWasmValue({})", 0)
1214
}
1315
}
16+
17+
impl From<u128> for RawSimdWasmValue {
18+
fn from(value: u128) -> Self {
19+
Self(value.to_le_bytes().into())
20+
}
21+
}
22+
23+
impl From<RawSimdWasmValue> for u128 {
24+
fn from(value: RawSimdWasmValue) -> Self {
25+
u128::from_le_bytes(value.0.into())
26+
}
27+
}

crates/tinywasm/src/runtime/stack/call_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl CallFrame {
8484
self.instr_ptr = break_to.instr_ptr;
8585

8686
// We also want to push the params to the stack
87-
values.break_to_params(&break_to);
87+
values.break_to_params(break_to);
8888

8989
// check if we're breaking to the loop
9090
if break_to_relative != 0 {
@@ -97,7 +97,7 @@ impl CallFrame {
9797
BlockType::Block | BlockType::If | BlockType::Else => {
9898
// this is a block, so we want to jump to the next instruction after the block ends
9999
// We also want to push the block's results to the stack
100-
values.break_to_results(&break_to);
100+
values.break_to_results(break_to);
101101

102102
// (the inst_ptr will be incremented by 1 before the next instruction is executed)
103103
self.instr_ptr = break_to.instr_ptr + break_to.end_instr_offset as usize;

crates/tinywasm/src/runtime/stack/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ mod block_stack;
22
mod call_stack;
33
mod value_stack;
44

5-
#[cfg(nightly)]
6-
mod simd_value_stack;
7-
85
pub(crate) use block_stack::{BlockFrame, BlockStack, BlockType};
96
pub(crate) use call_stack::{CallFrame, CallStack};
107
pub(crate) use value_stack::ValueStack;

0 commit comments

Comments
 (0)