use super::lanes::{
from_i16x8, from_i32x4, from_i64x2, from_u16x8, from_u32x4, from_u64x2, from_u8x16, u16x8,
u32x4, u64x2, u8x16,
};
use super::Execution;
use crate::instance::Instance;
use crate::module::op_simd::SimdOp;
use crate::store::StoreInner;
use crate::Result;
impl Execution {
#[allow(clippy::too_many_lines)] pub(super) fn exec_simd_mem(
&mut self,
inner: &mut StoreInner,
code: &crate::module::code::Code,
s: &SimdOp,
instance: Instance,
) -> Result<bool> {
use SimdOp as S;
match s {
S::V128Load(m) => {
let b = self.load_n::<16>(inner, code, instance, m)?;
self.push_v128(u128::from_le_bytes(b));
}
S::V128Store(m) => {
let v = self.pop_v128();
self.store_n::<16>(inner, code, instance, m, v.to_le_bytes())?;
}
S::V128Load8x8S(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i16x8(core::array::from_fn(|i| i16::from(b[i] as i8))));
}
S::V128Load8x8U(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i16x8(core::array::from_fn(|i| i16::from(b[i]))));
}
S::V128Load16x4S(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i32x4(core::array::from_fn(|i| {
i32::from(i16::from_le_bytes([b[2 * i], b[2 * i + 1]]))
})));
}
S::V128Load16x4U(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i32x4(core::array::from_fn(|i| {
i32::from(u16::from_le_bytes([b[2 * i], b[2 * i + 1]]))
})));
}
S::V128Load32x2S(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i64x2(core::array::from_fn(|i| {
i64::from(i32::from_le_bytes([
b[4 * i],
b[4 * i + 1],
b[4 * i + 2],
b[4 * i + 3],
]))
})));
}
S::V128Load32x2U(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_i64x2(core::array::from_fn(|i| {
i64::from(u32::from_le_bytes([
b[4 * i],
b[4 * i + 1],
b[4 * i + 2],
b[4 * i + 3],
]))
})));
}
S::V128Load8Splat(m) => {
let b = self.load_n::<1>(inner, code, instance, m)?;
self.push_v128(from_u8x16([b[0]; 16]));
}
S::V128Load16Splat(m) => {
let b = self.load_n::<2>(inner, code, instance, m)?;
self.push_v128(from_u16x8([u16::from_le_bytes(b); 8]));
}
S::V128Load32Splat(m) => {
let b = self.load_n::<4>(inner, code, instance, m)?;
self.push_v128(from_u32x4([u32::from_le_bytes(b); 4]));
}
S::V128Load64Splat(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(from_u64x2([u64::from_le_bytes(b); 2]));
}
S::V128Load32Zero(m) => {
let b = self.load_n::<4>(inner, code, instance, m)?;
self.push_v128(u128::from(u32::from_le_bytes(b)));
}
S::V128Load64Zero(m) => {
let b = self.load_n::<8>(inner, code, instance, m)?;
self.push_v128(u128::from(u64::from_le_bytes(b)));
}
S::V128Load8Lane { mem, lane } => {
let v = self.pop_v128();
let b = self.load_n::<1>(inner, code, instance, mem)?;
let mut a = u8x16(v);
a[*lane as usize] = b[0];
self.push_v128(from_u8x16(a));
}
S::V128Load16Lane { mem, lane } => {
let v = self.pop_v128();
let b = self.load_n::<2>(inner, code, instance, mem)?;
let mut a = u16x8(v);
a[*lane as usize] = u16::from_le_bytes(b);
self.push_v128(from_u16x8(a));
}
S::V128Load32Lane { mem, lane } => {
let v = self.pop_v128();
let b = self.load_n::<4>(inner, code, instance, mem)?;
let mut a = u32x4(v);
a[*lane as usize] = u32::from_le_bytes(b);
self.push_v128(from_u32x4(a));
}
S::V128Load64Lane { mem, lane } => {
let v = self.pop_v128();
let b = self.load_n::<8>(inner, code, instance, mem)?;
let mut a = u64x2(v);
a[*lane as usize] = u64::from_le_bytes(b);
self.push_v128(from_u64x2(a));
}
S::V128Store8Lane { mem, lane } => {
let a = u8x16(self.pop_v128());
self.store_n::<1>(inner, code, instance, mem, [a[*lane as usize]])?;
}
S::V128Store16Lane { mem, lane } => {
let a = u16x8(self.pop_v128());
self.store_n::<2>(inner, code, instance, mem, a[*lane as usize].to_le_bytes())?;
}
S::V128Store32Lane { mem, lane } => {
let a = u32x4(self.pop_v128());
self.store_n::<4>(inner, code, instance, mem, a[*lane as usize].to_le_bytes())?;
}
S::V128Store64Lane { mem, lane } => {
let a = u64x2(self.pop_v128());
self.store_n::<8>(inner, code, instance, mem, a[*lane as usize].to_le_bytes())?;
}
_ => return Ok(false),
}
Ok(true)
}
}