summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/parser/src/lib.rs4
-rw-r--r--crates/parser/src/visit.rs5
-rw-r--r--crates/tinywasm/Cargo.toml5
-rw-r--r--crates/tinywasm/src/interpreter/executor.rs36
-rw-r--r--crates/tinywasm/tests/generated/wasm-wide-arithmetic.csv1
-rw-r--r--crates/tinywasm/tests/test-wasm-wide-arithmetic.rs13
-rw-r--r--crates/types/src/instructions.rs5
7 files changed, 66 insertions, 3 deletions
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index a799f69..f7e713b 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -66,20 +66,20 @@ impl Parser {
custom_page_sizes: true,
bulk_memory_opt: true,
call_indirect_overlong: true,
+ wide_arithmetic: true,
+ relaxed_simd: true,
compact_imports: false,
cm_map: false,
custom_descriptors: false,
cm_threading: false,
extended_const: false,
- wide_arithmetic: false,
gc_types: true,
stack_switching: false,
component_model: false,
exceptions: false,
gc: false,
memory_control: false,
- relaxed_simd: true,
threads: false,
shared_everything_threads: false,
legacy_exceptions: false,
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index e3de009..d6bccdb 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -363,6 +363,7 @@ macro_rules! impl_visit_operator {
(@@saturating_float_to_int $($rest:tt)* ) => {};
(@@bulk_memory $($rest:tt)* ) => {};
(@@simd $($rest:tt)* ) => {};
+ (@@wide_arithmetic $($rest:tt)* ) => {};
(@@relaxed_simd $($rest:tt)* ) => {};
(@@tail_call $($rest:tt)* ) => {};
@@ -402,6 +403,10 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
visit_memory_init(MemoryInit, u32, u32), visit_memory_copy(MemoryCopy, u32, u32), visit_table_init(TableInit, u32, u32), visit_memory_fill(MemoryFill, u32), visit_data_drop(DataDrop, u32), visit_elem_drop(ElemDrop, u32)
}
+ define_operands! {
+ visit_i64_add128(I64Add128), visit_i64_sub128(I64Sub128), visit_i64_mul_wide_s(I64MulWideS), visit_i64_mul_wide_u(I64MulWideU)
+ }
+
fn visit_global_set(&mut self, global_index: u32) -> Self::Output {
match self.validator.get_operand_type(0) {
Some(Some(t)) => self.instructions.push(match t {
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index b89c907..274946a 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -104,6 +104,11 @@ harness=false
test=false
[[test]]
+name="test-wasm-wide-arithmetic"
+harness=false
+test=false
+
+[[test]]
name="test-wast"
harness=false
test=false
diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs
index 17343ee..2292a70 100644
--- a/crates/tinywasm/src/interpreter/executor.rs
+++ b/crates/tinywasm/src/interpreter/executor.rs
@@ -57,9 +57,25 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
(binary try $ty:ty, |$a:ident, $b:ident| $expr:expr) => { self.store.stack.values.binary::<$ty>(|$a, $b| $expr)? };
(unary $from:ty => $to:ty, |$v:ident| $expr:expr) => { self.store.stack.values.unary_into::<$from, $to>(|$v| Ok($expr))? };
(binary $from:ty => $to:ty, |$a:ident, $b:ident| $expr:expr) => { self.store.stack.values.binary_into::<$from, $to>(|$a, $b| Ok($expr))? };
+ (binary_into2 $from:ty => $to:ty, |$a:ident, $b:ident| $expr:expr) => {{
+ let $b = self.store.stack.values.pop::<$from>();
+ let $a = self.store.stack.values.pop::<$from>();
+ let out = $expr;
+ self.store.stack.values.push::<$to>(out.0)?;
+ self.store.stack.values.push::<$to>(out.1)?;
+ }};
(binary $a:ty, $b:ty, |$lhs:ident, $rhs:ident| $expr:expr) => { stack_op!(binary $a, $b => $b, |$lhs, $rhs| $expr) };
(binary $a:ty, $b:ty => $res:ty, |$lhs:ident, $rhs:ident| $expr:expr) => { self.store.stack.values.binary_mixed::<$a, $b, $res>(|$lhs, $rhs| Ok($expr))? };
(ternary $ty:ty, |$a:ident, $b:ident, $c:ident| $expr:expr) => { self.store.stack.values.ternary::<$ty>(|$a, $b, $c| Ok($expr))? };
+ (quaternary_into2 $from:ty => $to:ty, |$a:ident, $b:ident, $c:ident, $d:ident| $expr:expr) => {{
+ let $d = self.store.stack.values.pop::<$from>();
+ let $c = self.store.stack.values.pop::<$from>();
+ let $b = self.store.stack.values.pop::<$from>();
+ let $a = self.store.stack.values.pop::<$from>();
+ let out = $expr;
+ self.store.stack.values.push::<$to>(out.0)?;
+ self.store.stack.values.push::<$to>(out.1)?;
+ }};
(local_set_pop $ty:ty, $local_index:expr) => {{
let val = self.store.stack.values.pop::<$ty>();
self.store.stack.values.local_set(&self.cf, *$local_index, val);
@@ -266,6 +282,26 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
I64Rotl => stack_op!(binary i64, |a, b| a.wasm_rotl(b)),
I32Rotr => stack_op!(binary i32, |a, b| a.wasm_rotr(b)),
I64Rotr => stack_op!(binary i64, |a, b| a.wasm_rotr(b)),
+ I64Add128 => stack_op!(quaternary_into2 i64 => i64, |a_lo, a_hi, b_lo, b_hi| {
+ let lo = a_lo.wrapping_add(b_lo);
+ let carry = u64::from((lo as u64) < (a_lo as u64));
+ let hi = a_hi.wrapping_add(b_hi).wrapping_add(carry as i64);
+ (lo, hi)
+ }),
+ I64Sub128 => stack_op!(quaternary_into2 i64 => i64, |a_lo, a_hi, b_lo, b_hi| {
+ let lo = a_lo.wrapping_sub(b_lo);
+ let borrow = u64::from((a_lo as u64) < (b_lo as u64));
+ let hi = a_hi.wrapping_sub(b_hi).wrapping_sub(borrow as i64);
+ (lo, hi)
+ }),
+ I64MulWideS => stack_op!(binary_into2 i64 => i64, |a, b| {
+ let product = (a as i128).wrapping_mul(b as i128);
+ (product as i64, (product >> 64) as i64)
+ }),
+ I64MulWideU => stack_op!(binary_into2 i64 => i64, |a, b| {
+ let product = (a as u64 as u128).wrapping_mul(b as u64 as u128);
+ (product as u64 as i64, (product >> 64) as u64 as i64)
+ }),
I32Clz => stack_op!(unary i32, |v| v.leading_zeros() as i32),
I64Clz => stack_op!(unary i64, |v| i64::from(v.leading_zeros())),
I32Ctz => stack_op!(unary i32, |v| v.trailing_zeros() as i32),
diff --git a/crates/tinywasm/tests/generated/wasm-wide-arithmetic.csv b/crates/tinywasm/tests/generated/wasm-wide-arithmetic.csv
new file mode 100644
index 0000000..10d7685
--- /dev/null
+++ b/crates/tinywasm/tests/generated/wasm-wide-arithmetic.csv
@@ -0,0 +1 @@
+0.9.0-alpha.0,109,0,[{"name":"wide-arithmetic.wast","passed":109,"failed":0}]
diff --git a/crates/tinywasm/tests/test-wasm-wide-arithmetic.rs b/crates/tinywasm/tests/test-wasm-wide-arithmetic.rs
new file mode 100644
index 0000000..2aa6b43
--- /dev/null
+++ b/crates/tinywasm/tests/test-wasm-wide-arithmetic.rs
@@ -0,0 +1,13 @@
+mod testsuite;
+use eyre::Result;
+use testsuite::TestSuite;
+use wasm_testsuite::data::{Proposal, proposal};
+
+fn main() -> Result<()> {
+ TestSuite::set_log_level(log::LevelFilter::Off);
+
+ let mut test_suite = TestSuite::new();
+ test_suite.run_files(proposal(&Proposal::WideArithmetic))?;
+ test_suite.save_csv("./tests/generated/wasm-wide-arithmetic.csv", env!("CARGO_PKG_VERSION"))?;
+ test_suite.report_status()
+}
diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs
index 59dc49f..efb7172 100644
--- a/crates/types/src/instructions.rs
+++ b/crates/types/src/instructions.rs
@@ -176,7 +176,10 @@ pub enum Instruction {
DataDrop(DataAddr),
ElemDrop(ElemAddr),
- // > SIMD Instructions
+ // > Wide Arithmetic
+ I64Add128, I64Sub128, I64MulWideS, I64MulWideU,
+
+ // > SIMD
V128Load(MemoryArg),
V128Load8x8S(MemoryArg), V128Load8x8U(MemoryArg),
V128Load16x4S(MemoryArg), V128Load16x4U(MemoryArg),