tinywasm 0.9.0-alpha.0

A tiny WebAssembly interpreter
Documentation
use super::Value128;

#[cfg(not(feature = "std"))]
use crate::interpreter::no_std_floats::NoStdFloatExt;

impl Value128 {
    pub(super) fn extract_lane_bytes<const LANE_BYTES: usize>(self, lane: u8, lane_count: u8) -> [u8; LANE_BYTES] {
        debug_assert!(lane < lane_count);
        let bytes = self.0;
        let start = lane as usize * LANE_BYTES;
        let mut out = [0u8; LANE_BYTES];
        out.copy_from_slice(&bytes[start..start + LANE_BYTES]);
        out
    }

    pub(super) fn replace_lane_bytes<const LANE_BYTES: usize>(
        self,
        lane: u8,
        value: [u8; LANE_BYTES],
        lane_count: u8,
    ) -> Self {
        debug_assert!(lane < lane_count);
        let mut bytes = self.0;
        let start = lane as usize * LANE_BYTES;
        bytes[start..start + LANE_BYTES].copy_from_slice(&value);
        Self(bytes)
    }
}

pub(super) const fn canonicalize_simd_f32_nan(x: f32) -> f32 {
    #[cfg(feature = "canonicalize-nans")]
    if x.is_nan() {
        f32::NAN
    } else {
        x
    }
    #[cfg(not(feature = "canonicalize-nans"))]
    x
}

pub(super) const fn canonicalize_simd_f64_nan(x: f64) -> f64 {
    #[cfg(feature = "canonicalize-nans")]
    if x.is_nan() {
        f64::NAN
    } else {
        x
    }
    #[cfg(not(feature = "canonicalize-nans"))]
    x
}

pub(super) const fn saturate_i16_to_i8(x: i16) -> i8 {
    match x {
        v if v > i8::MAX as i16 => i8::MAX,
        v if v < i8::MIN as i16 => i8::MIN,
        v => v as i8,
    }
}

pub(super) const fn saturate_i16_to_u8(x: i16) -> u8 {
    match x {
        v if v <= 0 => 0,
        v if v > u8::MAX as i16 => u8::MAX,
        v => v as u8,
    }
}

pub(super) const fn saturate_i32_to_i16(x: i32) -> i16 {
    match x {
        v if v > i16::MAX as i32 => i16::MAX,
        v if v < i16::MIN as i32 => i16::MIN,
        v => v as i16,
    }
}

pub(super) const fn saturate_i32_to_u16(x: i32) -> u16 {
    match x {
        v if v <= 0 => 0,
        v if v > u16::MAX as i32 => u16::MAX,
        v => v as u16,
    }
}

pub(super) fn trunc_sat_f32_to_i32(v: f32) -> i32 {
    match v {
        x if x.is_nan() => 0,
        x if x <= i32::MIN as f32 - (1 << 8) as f32 => i32::MIN,
        x if x >= (i32::MAX as f32 + 1.0) => i32::MAX,
        x => x.trunc() as i32,
    }
}

pub(super) fn trunc_sat_f32_to_u32(v: f32) -> u32 {
    match v {
        x if x.is_nan() || x <= -1.0_f32 => 0,
        x if x >= (u32::MAX as f32 + 1.0) => u32::MAX,
        x => x.trunc() as u32,
    }
}

pub(super) fn trunc_sat_f64_to_i32(v: f64) -> i32 {
    match v {
        x if x.is_nan() => 0,
        x if x <= i32::MIN as f64 - 1.0_f64 => i32::MIN,
        x if x >= (i32::MAX as f64 + 1.0) => i32::MAX,
        x => x.trunc() as i32,
    }
}

pub(super) fn trunc_sat_f64_to_u32(v: f64) -> u32 {
    match v {
        x if x.is_nan() || x <= -1.0_f64 => 0,
        x if x >= (u32::MAX as f64 + 1.0) => u32::MAX,
        x => x.trunc() as u32,
    }
}