summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-09-02 22:49:51 +0200
committerHenry Gressmann <mail@henrygressmann.de>2024-09-02 22:49:51 +0200
commit86bcc87de2163f4b83e1e3f4bfa3dd7ec6482284 (patch)
tree123b5c8fe41cd63508a700d363d1aecc2b2ea89e
parent07804aa2291c2e09bf80e0826b5a693646a6a67a (diff)
wip: simd support
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--crates/parser/src/lib.rs4
-rw-r--r--crates/tinywasm/tests/generated/wasm-annotations.csv1
-rw-r--r--crates/tinywasm/tests/generated/wasm-memory64.csv1
-rw-r--r--crates/tinywasm/tests/generated/wasm-simd.csv1
-rw-r--r--crates/tinywasm/tests/test-wasm-memory64.rs10
-rw-r--r--crates/tinywasm/tests/testsuite/mod.rs4
-rw-r--r--crates/tinywasm/tests/testsuite/util.rs23
-rw-r--r--crates/types/src/value.rs64
8 files changed, 104 insertions, 4 deletions
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index dfe6b0c..5e8f9e0 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -61,6 +61,8 @@ impl Parser {
function_references: true,
tail_call: true,
multi_memory: true,
+ memory64: false,
+ simd: true,
gc_types: true,
component_model: false,
@@ -70,10 +72,8 @@ impl Parser {
exceptions: false,
extended_const: false,
gc: false,
- memory64: false,
memory_control: false,
relaxed_simd: false,
- simd: false,
threads: false,
custom_page_sizes: false,
shared_everything_threads: false,
diff --git a/crates/tinywasm/tests/generated/wasm-annotations.csv b/crates/tinywasm/tests/generated/wasm-annotations.csv
new file mode 100644
index 0000000..582bc1b
--- /dev/null
+++ b/crates/tinywasm/tests/generated/wasm-annotations.csv
@@ -0,0 +1 @@
+0.8.0,331,286,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"token.wast","passed":61,"failed":0}]
diff --git a/crates/tinywasm/tests/generated/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv
new file mode 100644
index 0000000..5c9f985
--- /dev/null
+++ b/crates/tinywasm/tests/generated/wasm-memory64.csv
@@ -0,0 +1 @@
+0.8.0,15074,3213,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":162,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":107,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":28,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":50},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}]
diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv
new file mode 100644
index 0000000..e9bc8ae
--- /dev/null
+++ b/crates/tinywasm/tests/generated/wasm-simd.csv
@@ -0,0 +1 @@
+0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}]
diff --git a/crates/tinywasm/tests/test-wasm-memory64.rs b/crates/tinywasm/tests/test-wasm-memory64.rs
index ab23762..0dfe2b8 100644
--- a/crates/tinywasm/tests/test-wasm-memory64.rs
+++ b/crates/tinywasm/tests/test-wasm-memory64.rs
@@ -5,6 +5,16 @@ use testsuite::TestSuite;
fn main() -> Result<()> {
let mut test_suite = TestSuite::new();
+ test_suite.skip("memory64/array.wast");
+ test_suite.skip("memory64/extern.wast");
+ test_suite.skip("memory64/global.wast");
+ test_suite.skip("memory64/i31.wast");
+ test_suite.skip("memory64/ref_null.wast");
+ test_suite.skip("memory64/select.wast");
+ test_suite.skip("memory64/simd_address.wast");
+ test_suite.skip("memory64/simd_lane.wast");
+ test_suite.skip("memory64/struct.wast");
+ test_suite.skip("memory64/table.wast");
TestSuite::set_log_level(log::LevelFilter::Off);
test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("memory64"))?;
diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs
index ca62d4e..3c23e00 100644
--- a/crates/tinywasm/tests/testsuite/mod.rs
+++ b/crates/tinywasm/tests/testsuite/mod.rs
@@ -50,6 +50,10 @@ impl TestSuite {
Self(BTreeMap::new(), Vec::new())
}
+ pub fn skip(&mut self, name: &str) {
+ self.1.push(name.to_string());
+ }
+
pub fn failed(&self) -> bool {
self.0.values().any(|group| group.stats().1 > 0)
}
diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs
index 29f028b..16fc01c 100644
--- a/crates/tinywasm/tests/testsuite/util.rs
+++ b/crates/tinywasm/tests/testsuite/util.rs
@@ -97,12 +97,13 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result<tinywasm_types::WasmValue
return Err(eyre!("unsupported arg type: Component"));
};
- use wast::core::WastArgCore::{RefExtern, RefNull, F32, F64, I32, I64};
+ use wast::core::WastArgCore::{RefExtern, RefNull, F32, F64, I32, I64, V128};
Ok(match arg {
F32(f) => WasmValue::F32(f32::from_bits(f.bits)),
F64(f) => WasmValue::F64(f64::from_bits(f.bits)),
I32(i) => WasmValue::I32(i),
I64(i) => WasmValue::I64(i),
+ V128(i) => WasmValue::V128(i128::from_le_bytes(i.to_le_bytes()).try_into().unwrap()),
RefExtern(v) => WasmValue::RefExtern(v),
RefNull(t) => match t {
wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func } => {
@@ -117,17 +118,33 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result<tinywasm_types::WasmValue
})
}
+fn wast_i128_to_i128(i: wast::core::V128Pattern) -> u128 {
+ match i {
+ wast::core::V128Pattern::F32x4(f) => {
+ f.iter().fold(0, |acc, &f| acc << 32 | nanpattern2tinywasmvalue(f).unwrap().as_f32().unwrap() as u128)
+ }
+ wast::core::V128Pattern::F64x2(f) => {
+ f.iter().fold(0, |acc, &f| acc << 64 | nanpattern2tinywasmvalue(f).unwrap().as_f64().unwrap() as u128)
+ }
+ wast::core::V128Pattern::I16x8(f) => f.iter().fold(0, |acc, &f| acc << 16 | f as u128),
+ wast::core::V128Pattern::I32x4(f) => f.iter().fold(0, |acc, &f| acc << 32 | f as u128),
+ wast::core::V128Pattern::I64x2(f) => f.iter().fold(0, |acc, &f| acc << 64 | f as u128),
+ wast::core::V128Pattern::I8x16(f) => f.iter().fold(0, |acc, &f| acc << 8 | f as u128),
+ }
+}
+
fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result<tinywasm_types::WasmValue> {
let wast::WastRet::Core(ret) = ret else {
return Err(eyre!("unsupported arg type"));
};
- use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64};
+ use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64, V128};
Ok(match ret {
F32(f) => nanpattern2tinywasmvalue(f)?,
F64(f) => nanpattern2tinywasmvalue(f)?,
I32(i) => WasmValue::I32(i),
I64(i) => WasmValue::I64(i),
+ V128(i) => WasmValue::V128(wast_i128_to_i128(i)),
RefNull(t) => match t {
Some(wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func }) => {
WasmValue::RefNull(ValType::RefFunc)
@@ -139,10 +156,12 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result<tinywasm_types::WasmValue
},
RefExtern(v) => match v {
Some(v) => WasmValue::RefExtern(v),
+ None => WasmValue::RefNull(ValType::RefExtern),
_ => return Err(eyre!("unsupported arg type: refextern: {:?}", v)),
},
RefFunc(v) => match v {
Some(wast::token::Index::Num(n, _)) => WasmValue::RefFunc(n),
+ None => WasmValue::RefNull(ValType::RefFunc),
_ => return Err(eyre!("unsupported arg type: reffunc: {:?}", v)),
},
a => return Err(eyre!("unsupported arg type {:?}", a)),
diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs
index 416f678..825fa1f 100644
--- a/crates/types/src/value.rs
+++ b/crates/types/src/value.rs
@@ -79,6 +79,70 @@ impl WasmValue {
_ => false,
}
}
+
+ #[doc(hidden)]
+ pub fn as_i32(&self) -> Option<i32> {
+ match self {
+ Self::I32(i) => Some(*i),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_i64(&self) -> Option<i64> {
+ match self {
+ Self::I64(i) => Some(*i),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_f32(&self) -> Option<f32> {
+ match self {
+ Self::F32(i) => Some(*i),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_f64(&self) -> Option<f64> {
+ match self {
+ Self::F64(i) => Some(*i),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_v128(&self) -> Option<u128> {
+ match self {
+ Self::V128(i) => Some(*i),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_ref_extern(&self) -> Option<ExternAddr> {
+ match self {
+ Self::RefExtern(addr) => Some(*addr),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_ref_func(&self) -> Option<FuncAddr> {
+ match self {
+ Self::RefFunc(addr) => Some(*addr),
+ _ => None,
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn as_ref_null(&self) -> Option<ValType> {
+ match self {
+ Self::RefNull(ty) => Some(*ty),
+ _ => None,
+ }
+ }
}
#[cold]