From 2911204b3b2508c729c2584016cccd3ef57ffc91 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 8 Dec 2025 21:58:16 +0100 Subject: chore: update everything, more simd stuff Signed-off-by: Henry Gressmann --- crates/parser/src/conversion.rs | 8 +- crates/tinywasm/src/interpreter/executor.rs | 134 ++++++++++---------- crates/tinywasm/src/interpreter/value128.rs | 141 +++++++++++++++++++++ crates/tinywasm/src/store/memory.rs | 13 +- .../tests/generated/wasm-custom-page-sizes.csv | 2 +- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- 6 files changed, 220 insertions(+), 80 deletions(-) (limited to 'crates') diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index a4e3b35..b62e670 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -94,6 +94,12 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result { return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported import kind: {ty:?}"))); } + _ => { + return Err(crate::ParseError::UnsupportedOperator(format!( + "Unsupported import kind: {:?}", + import.ty + ))); + } }, }) } @@ -156,7 +162,7 @@ pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result ExternalKind::Table, wasmparser::ExternalKind::Memory => ExternalKind::Memory, wasmparser::ExternalKind::Global => ExternalKind::Global, - wasmparser::ExternalKind::Tag => { + wasmparser::ExternalKind::Tag | wasmparser::ExternalKind::FuncExact => { return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported export kind: {:?}", export.kind))); } }; diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 8033a4e..f026244 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -318,45 +318,45 @@ impl<'store, 'stack> Executor<'store, 'stack> { V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle(s))).to_cf()?, - // V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, - // V128Load8x8S(_arg) => unimplemented!(), - // V128Load8x8U(_arg) => unimplemented!(), - // V128Load16x4S(_arg) => unimplemented!(), - // V128Load16x4U(_arg) => unimplemented!(), - // V128Load32x2S(_arg) => unimplemented!(), - // V128Load32x2U(_arg) => unimplemented!(), - // V128Load8Splat(_arg) => unimplemented!(), - // V128Load16Splat(_arg) => unimplemented!(), - // V128Load32Splat(_arg) => unimplemented!(), - // V128Load64Splat(_arg) => unimplemented!(), - - // V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, - - // V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - // V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - // V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - // V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - - // // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. - // V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { - // let bytes = v.to_le_bytes(); - // u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - // })?, - // V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { - // let bytes = v.to_le_bytes(); - // u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) - // })?, - - // V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), - - // I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - // I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - // I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - // I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - // I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - // I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - // F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - // F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, + V128Load8x8S(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), Value128::extend_8_i8)?, + V128Load8x8U(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::extend_8_u8)?, + V128Load16x4S(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::extend_4_i16)?, + V128Load16x4U(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::extend_4_u16)?, + V128Load32x2S(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::extend_2_i32)?, + V128Load32x2U(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::extend_2_u32)?, + V128Load8Splat(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::splat_i8)?, + V128Load16Splat(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::splat_i16)?, + V128Load32Splat(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::splat_i32)?, + V128Load64Splat(_arg) => self.exec_mem_load::(_arg.mem_addr(), _arg.offset(), Value128::splat_i64)?, + + V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, + + V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + + // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. + V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + let bytes = v.to_le_bytes(); + Value128::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + })?, + V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + let bytes = v.to_le_bytes(); + Value128::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) + })?, + + V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].into()), + + // I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, // V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, // V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, @@ -1038,18 +1038,14 @@ impl<'store, 'stack> Executor<'store, 'stack> { } } - // fn exec_mem_load_lane< - // LOAD: MemLoadable, - // INTO: InternalValue + IndexMut, - // const LOAD_SIZE: usize, - // >( + // fn exec_mem_load_lane, const LOAD_SIZE: usize>( // &mut self, // mem_addr: tinywasm_types::MemAddr, // offset: u64, // lane: u8, // ) -> ControlFlow> { // let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); - // let mut imm = self.stack.values.pop::(); + // let mut imm = self.stack.values.pop::().to_mem_bytes(); // let val = self.stack.values.pop::() as u64; // let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { // cold(); @@ -1059,13 +1055,15 @@ impl<'store, 'stack> Executor<'store, 'stack> { // max: 0, // }))); // }; - // let val = mem.load_as::(addr).to_cf()?; - // imm[lane as usize] = val; - // self.stack.values.push(imm); + // let val = mem.load_as::(addr).to_cf()?.to_mem_bytes(); + + // // imm[lane as usize] = val; + + // self.stack.values.push(Value128::from_mem_bytes(imm)); // ControlFlow::Continue(()) // } - fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( + fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( &mut self, mem_addr: tinywasm_types::MemAddr, offset: u64, @@ -1091,29 +1089,29 @@ impl<'store, 'stack> Executor<'store, 'stack> { ControlFlow::Continue(()) } - // fn exec_mem_store_lane, U: MemStorable + Copy, const N: usize>( - // &mut self, - // mem_addr: tinywasm_types::MemAddr, - // offset: u64, - // lane: u8, - // ) -> ControlFlow> { - // let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); - // let val = self.stack.values.pop::(); - // let val = val[lane as usize].to_mem_bytes(); + fn exec_mem_store_lane + Copy, const N: usize>( + &mut self, + mem_addr: tinywasm_types::MemAddr, + offset: u64, + lane: u8, + ) -> ControlFlow> { + let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); + let val = self.stack.values.pop::().to_mem_bytes(); + let val = val[lane as usize].to_mem_bytes(); - // let addr = match mem.is_64bit() { - // true => self.stack.values.pop::() as u64, - // false => self.stack.values.pop::() as u32 as u64, - // }; + let addr = match mem.is_64bit() { + true => self.stack.values.pop::() as u64, + false => self.stack.values.pop::() as u32 as u64, + }; - // if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { - // return ControlFlow::Break(Some(e)); - // } + if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { + return ControlFlow::Break(Some(e)); + } - // ControlFlow::Continue(()) - // } + ControlFlow::Continue(()) + } - fn exec_mem_store, const N: usize>( + fn exec_mem_store, const N: usize>( &mut self, mem_addr: tinywasm_types::MemAddr, offset: u64, diff --git a/crates/tinywasm/src/interpreter/value128.rs b/crates/tinywasm/src/interpreter/value128.rs index 12d70e5..b9c96a9 100644 --- a/crates/tinywasm/src/interpreter/value128.rs +++ b/crates/tinywasm/src/interpreter/value128.rs @@ -33,6 +33,147 @@ impl Value128 { } Self::from_le_bytes(result_bytes) } + + pub const fn extend_8_i8(src: i8) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 8 { + result_bytes[i * 2] = src as u8; + result_bytes[i * 2 + 1] = if src < 0 { 0xFF } else { 0x00 }; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn extend_8_u8(src: u8) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 8 { + result_bytes[i * 2] = src; + result_bytes[i * 2 + 1] = 0x00; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn extend_4_i16(src: i16) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 4 { + let bytes = src.to_le_bytes(); + result_bytes[i * 4] = bytes[0]; + result_bytes[i * 4 + 1] = bytes[1]; + result_bytes[i * 4 + 2] = if src < 0 { 0xFF } else { 0x00 }; + result_bytes[i * 4 + 3] = if src < 0 { 0xFF } else { 0x00 }; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn extend_4_u16(src: u16) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 4 { + let bytes = src.to_le_bytes(); + result_bytes[i * 4] = bytes[0]; + result_bytes[i * 4 + 1] = bytes[1]; + result_bytes[i * 4 + 2] = 0x00; + result_bytes[i * 4 + 3] = 0x00; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn extend_2_i32(src: i32) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 2 { + let bytes = src.to_le_bytes(); + result_bytes[i * 8] = bytes[0]; + result_bytes[i * 8 + 1] = bytes[1]; + result_bytes[i * 8 + 2] = bytes[2]; + result_bytes[i * 8 + 3] = bytes[3]; + result_bytes[i * 8 + 4] = if src < 0 { 0xFF } else { 0x00 }; + result_bytes[i * 8 + 5] = if src < 0 { 0xFF } else { 0x00 }; + result_bytes[i * 8 + 6] = if src < 0 { 0xFF } else { 0x00 }; + result_bytes[i * 8 + 7] = if src < 0 { 0xFF } else { 0x00 }; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn extend_2_u32(src: u32) -> Self { + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 2 { + let bytes = src.to_le_bytes(); + result_bytes[i * 8] = bytes[0]; + result_bytes[i * 8 + 1] = bytes[1]; + result_bytes[i * 8 + 2] = bytes[2]; + result_bytes[i * 8 + 3] = bytes[3]; + result_bytes[i * 8 + 4] = 0x00; + result_bytes[i * 8 + 5] = 0x00; + result_bytes[i * 8 + 6] = 0x00; + result_bytes[i * 8 + 7] = 0x00; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn splat_i8(src: i8) -> Self { + let mut result_bytes = [0u8; 16]; + let byte = src as u8; + let mut i = 0; + while i < 16 { + result_bytes[i] = byte; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn splat_i16(src: i16) -> Self { + let mut result_bytes = [0u8; 16]; + let bytes = src.to_le_bytes(); + let mut i = 0; + while i < 8 { + result_bytes[i * 2] = bytes[0]; + result_bytes[i * 2 + 1] = bytes[1]; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn splat_i32(src: i32) -> Self { + let mut result_bytes = [0u8; 16]; + let bytes = src.to_le_bytes(); + let mut i = 0; + while i < 4 { + result_bytes[i * 4] = bytes[0]; + result_bytes[i * 4 + 1] = bytes[1]; + result_bytes[i * 4 + 2] = bytes[2]; + result_bytes[i * 4 + 3] = bytes[3]; + i += 1; + } + Self::from_le_bytes(result_bytes) + } + + pub const fn splat_i64(src: i64) -> Self { + let mut result_bytes = [0u8; 16]; + let bytes = src.to_le_bytes(); + let mut i = 0; + while i < 2 { + result_bytes[i * 8] = bytes[0]; + result_bytes[i * 8 + 1] = bytes[1]; + result_bytes[i * 8 + 2] = bytes[2]; + result_bytes[i * 8 + 3] = bytes[3]; + result_bytes[i * 8 + 4] = bytes[4]; + result_bytes[i * 8 + 5] = bytes[5]; + result_bytes[i * 8 + 6] = bytes[6]; + result_bytes[i * 8 + 7] = bytes[7]; + i += 1; + } + Self::from_le_bytes(result_bytes) + } } impl From for i128 { diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index 267ca9a..8898212 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -76,7 +76,7 @@ impl MemoryInstance { Ok(&self.data[addr..end]) } - pub(crate) fn load_as>(&self, addr: usize) -> Result { + pub(crate) fn load_as>(&self, addr: usize) -> Result { let Some(end) = addr.checked_add(SIZE) else { return Err(self.trap_oob(addr, SIZE)); }; @@ -152,14 +152,11 @@ impl MemoryInstance { } } -/// A trait for types that can be stored in memory -pub(crate) trait MemStorable { +/// A trait for types that can be converted to and from static byte arrays +pub(crate) trait MemValue: Copy + Sized { /// Store a value in memory fn to_mem_bytes(self) -> [u8; N]; -} -/// A trait for types that can be loaded from memory -pub(crate) trait MemLoadable: Sized + Copy { /// Load a value from memory fn from_mem_bytes(bytes: [u8; N]) -> Self; } @@ -167,14 +164,12 @@ pub(crate) trait MemLoadable: Sized + Copy { macro_rules! impl_mem_traits { ($($ty:ty, $size:expr),*) => { $( - impl MemLoadable<$size> for $ty { + impl MemValue<$size> for $ty { #[inline(always)] fn from_mem_bytes(bytes: [u8; $size]) -> Self { <$ty>::from_le_bytes(bytes.into()) } - } - impl MemStorable<$size> for $ty { #[inline(always)] fn to_mem_bytes(self) -> [u8; $size] { self.to_le_bytes().into() diff --git a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv index 5ba121e..1761a0a 100644 --- a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv +++ b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv @@ -1,2 +1,2 @@ 0.8.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] -0.9.0-alpha.0,76,0,[{"name":"custom-page-sizes-invalid.wast","passed":23,"failed":0},{"name":"custom-page-sizes.wast","passed":45,"failed":0},{"name":"memory_max.wast","passed":4,"failed":0},{"name":"memory_max_i64.wast","passed":4,"failed":0}] +0.9.0-alpha.0,80,0,[{"name":"custom-page-sizes-invalid.wast","passed":23,"failed":0},{"name":"custom-page-sizes.wast","passed":45,"failed":0},{"name":"memory_max.wast","passed":6,"failed":0},{"name":"memory_max_i64.wast","passed":6,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index 73e3b92..f87cc69 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 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}] -0.9.0-alpha.0,24450,1539,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":790,"failed":0},{"name":"simd_f32x4_arith.wast","passed":1822,"failed":0},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":187,"failed":14},{"name":"simd_f64x2.wast","passed":803,"failed":0},{"name":"simd_f64x2_arith.wast","passed":1824,"failed":1},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":187,"failed":14},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":18},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":113,"failed":0},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":39,"failed":0},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_select.wast","passed":7,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":36,"failed":0},{"name":"simd_store32_lane.wast","passed":24,"failed":0},{"name":"simd_store64_lane.wast","passed":16,"failed":0},{"name":"simd_store8_lane.wast","passed":52,"failed":0}] +0.9.0-alpha.0,2460,23529,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":139,"failed":138},{"name":"simd_const.wast","passed":755,"failed":2},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":28},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":213,"failed":262},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":29,"failed":10},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":30,"failed":74},{"name":"simd_load_splat.wast","passed":122,"failed":4},{"name":"simd_load_zero.wast","passed":37,"failed":2},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_select.wast","passed":7,"failed":0},{"name":"simd_splat.wast","passed":27,"failed":158},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":4,"failed":32},{"name":"simd_store32_lane.wast","passed":4,"failed":20},{"name":"simd_store64_lane.wast","passed":4,"failed":12},{"name":"simd_store8_lane.wast","passed":52,"failed":0}] -- cgit v1.3.1