sonic-rs 0.3.10

Sonic-rs is a fast Rust JSON library based on SIMD
Documentation
use std::ops::{BitAnd, BitOr, BitOrAssign};

use super::{bits::combine_u16, Mask, Mask128, Simd, Simd128i, Simd128u};
use crate::impl_lanes;

impl_lanes!(Simd256u, 32);

impl_lanes!(Mask256, 32);

#[derive(Debug)]
#[repr(transparent)]
pub struct Simd256u((Simd128u, Simd128u));

#[derive(Debug)]
#[repr(transparent)]
pub struct Simd256i((Simd128i, Simd128i));

#[derive(Debug)]
#[repr(transparent)]
pub struct Mask256(pub(crate) (Mask128, Mask128));

impl Mask for Mask256 {
    type BitMask = u32;
    type Element = u8;

    #[inline(always)]
    fn bitmask(self) -> Self::BitMask {
        cfg_if::cfg_if! {
            if #[cfg(all(target_feature="neon", target_arch="aarch64"))] {
                use std::arch::aarch64::uint8x16_t;
                let(v0, v1) = self.0;
                unsafe { super::neon::to_bitmask32(v0.0, v1.0) }
            } else {
                combine_u16(self.0 .0.bitmask(), self.0 .1.bitmask())
            }
        }
    }

    #[inline(always)]
    fn splat(b: bool) -> Self {
        Mask256((Mask128::splat(b), Mask128::splat(b)))
    }
}

impl BitOr for Mask256 {
    type Output = Self;

    #[inline(always)]
    fn bitor(self, rhs: Self) -> Self::Output {
        let lo = self.0 .0 | rhs.0 .0;
        let hi = self.0 .1 | rhs.0 .1;
        Mask256((lo, hi))
    }
}

impl BitOrAssign for Mask256 {
    #[inline(always)]
    fn bitor_assign(&mut self, rhs: Self) {
        self.0 .0 |= rhs.0 .0;
        self.0 .1 |= rhs.0 .1;
    }
}

impl BitAnd<Mask256> for Mask256 {
    type Output = Self;

    #[inline(always)]
    fn bitand(self, rhs: Mask256) -> Self::Output {
        let lo = self.0 .0 & rhs.0 .0;
        let hi = self.0 .1 & rhs.0 .1;
        Mask256((lo, hi))
    }
}

impl Simd for Simd256u {
    const LANES: usize = 32;

    type Mask = Mask256;
    type Element = u8;

    #[inline(always)]
    unsafe fn loadu(ptr: *const u8) -> Self {
        let lo = Simd128u::loadu(ptr);
        let hi = Simd128u::loadu(ptr.add(Simd128u::LANES));
        Simd256u((lo, hi))
    }

    #[inline(always)]
    unsafe fn storeu(&self, ptr: *mut u8) {
        Simd128u::storeu(&self.0 .0, ptr);
        Simd128u::storeu(&self.0 .1, ptr.add(Simd128u::LANES));
    }

    #[inline(always)]
    fn eq(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.eq(&rhs.0 .0);
        let hi = self.0 .1.eq(&rhs.0 .1);
        Mask256((lo, hi))
    }

    #[inline(always)]
    fn splat(elem: u8) -> Self {
        Simd256u((Simd128u::splat(elem), Simd128u::splat(elem)))
    }

    #[inline(always)]
    fn le(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.le(&rhs.0 .0);
        let hi = self.0 .1.le(&rhs.0 .1);
        Mask256((lo, hi))
    }

    #[inline(always)]
    fn gt(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.gt(&rhs.0 .0);
        let hi = self.0 .1.gt(&rhs.0 .1);
        Mask256((lo, hi))
    }
}

impl Simd for Simd256i {
    const LANES: usize = 32;

    type Mask = Mask256;
    type Element = i8;

    #[inline(always)]
    unsafe fn loadu(ptr: *const u8) -> Self {
        let lo = Simd128i::loadu(ptr);
        let hi = Simd128i::loadu(ptr.add(Simd128i::LANES));
        Simd256i((lo, hi))
    }

    #[inline(always)]
    unsafe fn storeu(&self, ptr: *mut u8) {
        Simd128i::storeu(&self.0 .0, ptr);
        Simd128i::storeu(&self.0 .1, ptr.add(Simd128i::LANES));
    }

    #[inline(always)]
    fn eq(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.eq(&rhs.0 .0);
        let hi = self.0 .1.eq(&rhs.0 .1);
        Mask256((lo, hi))
    }

    #[inline(always)]
    fn splat(elem: i8) -> Self {
        Simd256i((Simd128i::splat(elem), Simd128i::splat(elem)))
    }

    #[inline(always)]
    fn le(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.le(&rhs.0 .0);
        let hi = self.0 .1.le(&rhs.0 .1);
        Mask256((lo, hi))
    }

    #[inline(always)]
    fn gt(&self, rhs: &Self) -> Self::Mask {
        let lo = self.0 .0.gt(&rhs.0 .0);
        let hi = self.0 .1.gt(&rhs.0 .1);
        Mask256((lo, hi))
    }
}