use super::*;
#[inline(always)]
pub fn bx4_to_i32x4x(value: generic_array::GenericArray<bool, generic_array::typenum::U4>) -> v128 {
#[rustfmt::skip]
let mask = i8x16(
value[0] as i8,
value[1] as i8,
value[2] as i8,
value[3] as i8,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
);
i32x4_extend_low_i16x8(i16x8_extend_low_i8x16(i8x16_neg(mask)))
}
#[inline(always)]
pub fn bx2_to_i64x2x(value: generic_array::GenericArray<bool, generic_array::typenum::U2>) -> v128 {
#[rustfmt::skip]
let mask = i8x16(
value[0] as i8, value[0] as i8, value[1] as i8, value[1] as i8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
);
i32x4_extend_low_i16x8(i16x8_extend_low_i8x16(i8x16_neg(mask)))
}
#[inline(always)]
pub fn convert_u64x2_to_f64x2(v: v128) -> v128 {
let magic_i_lo = u64x2_splat(0x4330000000000000); let magic_i_hi32 = u64x2_splat(0x4530000000000000); let magic_d_all = u64x2_splat(0x4530000000100000);
let v_lo = i32x4_shuffle::<0, 5, 2, 7>(v, magic_i_lo);
let v_shr = u64x2_shr(v, 32);
let v_hi = v128_xor(v_shr, magic_i_hi32);
let v_hi_dbl = f64x2_sub(v_hi, magic_d_all);
f64x2_add(v_hi_dbl, v_lo)
}
#[inline(always)]
pub fn convert_i64x2_to_f64x2(v: v128) -> v128 {
let magic_i_lo = u64x2_splat(0x4330000000000000); let magic_i_hi32 = u64x2_splat(0x4530000080000000); let magic_d_all = u64x2_splat(0x4530000080100000);
let v_lo = i32x4_shuffle::<0, 5, 2, 7>(v, magic_i_lo);
let v_shr = u64x2_shr(v, 32);
let v_hi = v128_xor(v_shr, magic_i_hi32);
let v_hi_dbl = f64x2_sub(v_hi, magic_d_all);
f64x2_add(v_hi_dbl, v_lo)
}
#[inline(always)]
unsafe fn store_dwords(v: v128) -> [i32; 4] {
let mut arr = [0i32; 4];
v128_store(arr.as_mut_ptr() as *mut _, v);
arr
}
#[inline(always)]
unsafe fn store_qwords(v: v128) -> [i64; 2] {
let mut arr = [0i64; 2];
v128_store(arr.as_mut_ptr() as *mut _, v);
arr
}
#[inline(always)]
unsafe fn store_words(v: v128) -> [i16; 8] {
let mut arr = [0i16; 8];
v128_store(arr.as_mut_ptr() as *mut _, v);
arr
}
#[inline(always)]
pub unsafe fn widen_i8_to_i32(v: v128) -> v128 {
i32x4_extend_low_i16x8(i16x8_extend_low_i8x16(v))
}
#[inline(always)]
pub unsafe fn widen_u8_to_u32(v: v128) -> v128 {
i32x4_extend_low_u16x8(i16x8_extend_low_u8x16(v))
}
#[inline(always)]
pub unsafe fn widen_i8x16_to_4xi32x4(v: v128) -> [v128; 4] {
[
widen_i8_to_i32(v),
widen_i8_to_i32(i32x4_shuffle::<1, 0, 0, 0>(v, v)),
widen_i8_to_i32(i32x4_shuffle::<2, 0, 0, 0>(v, v)),
widen_i8_to_i32(i32x4_shuffle::<3, 0, 0, 0>(v, v)),
]
}
#[inline(always)]
pub unsafe fn widen_u8x16_to_4xu32x4(v: v128) -> [v128; 4] {
[
widen_u8_to_u32(v),
widen_u8_to_u32(i32x4_shuffle::<1, 0, 0, 0>(v, v)),
widen_u8_to_u32(i32x4_shuffle::<2, 0, 0, 0>(v, v)),
widen_u8_to_u32(i32x4_shuffle::<3, 0, 0, 0>(v, v)),
]
}
#[inline(always)]
pub unsafe fn narrow_2xi16x8_to_bytes(v: [v128; 2]) -> v128 {
#[rustfmt::skip]
let r = i8x16_shuffle::<
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
>(v[0], v[1]);
r
}
#[inline(always)]
pub unsafe fn narrow_4xi32x4_to_bytes(v: [v128; 4]) -> v128 {
let a = store_dwords(v[0]);
let b = store_dwords(v[1]);
let c = store_dwords(v[2]);
let d = store_dwords(v[3]);
i8x16(
a[0] as i8, a[1] as i8, a[2] as i8, a[3] as i8, b[0] as i8, b[1] as i8, b[2] as i8, b[3] as i8, c[0] as i8,
c[1] as i8, c[2] as i8, c[3] as i8, d[0] as i8, d[1] as i8, d[2] as i8, d[3] as i8,
)
}
#[inline(always)]
pub unsafe fn widen_i16x8_to_4xi64x2(v: v128) -> [v128; 4] {
let a = store_words(v);
[
i64x2(a[0] as i64, a[1] as i64),
i64x2(a[2] as i64, a[3] as i64),
i64x2(a[4] as i64, a[5] as i64),
i64x2(a[6] as i64, a[7] as i64),
]
}
#[inline(always)]
pub unsafe fn widen_u16x8_to_4xu64x2(v: v128) -> [v128; 4] {
let a = store_words(v);
[
u64x2(a[0] as u16 as u64, a[1] as u16 as u64),
u64x2(a[2] as u16 as u64, a[3] as u16 as u64),
u64x2(a[4] as u16 as u64, a[5] as u16 as u64),
u64x2(a[6] as u16 as u64, a[7] as u16 as u64),
]
}
#[inline(always)]
pub unsafe fn narrow_4xi64x2_to_words(v: [v128; 4]) -> v128 {
let a = store_qwords(v[0]);
let b = store_qwords(v[1]);
let c = store_qwords(v[2]);
let d = store_qwords(v[3]);
i16x8(
a[0] as i16,
a[1] as i16,
b[0] as i16,
b[1] as i16,
c[0] as i16,
c[1] as i16,
d[0] as i16,
d[1] as i16,
)
}
#[inline(always)]
pub unsafe fn f64x2_to_2xi32(v: v128) -> [i32; 2] {
let d = store_dwords(i32x4_trunc_sat_f64x2_zero(v));
[d[0], d[1]]
}
#[inline(always)]
pub unsafe fn i32x4_to_2xf64x2(ints: v128) -> [v128; 2] {
[
f64x2_convert_low_i32x4(ints),
f64x2_convert_low_i32x4(i32x4_shuffle::<2, 3, 2, 3>(ints, ints)),
]
}
#[inline(always)]
pub unsafe fn u32x4_to_2xf64x2(ints: v128) -> [v128; 2] {
[
f64x2_convert_low_u32x4(ints),
f64x2_convert_low_u32x4(i32x4_shuffle::<2, 3, 2, 3>(ints, ints)),
]
}
#[inline(always)]
pub fn bitmask_to_i32x4x(bitmask: u64) -> v128 {
const BITS: v128 = u32x4(1, 2, 4, 8);
i32x4_eq(v128_and(u32x4_splat(bitmask as u32), BITS), BITS)
}
#[inline(always)]
pub fn bitmask_to_i64x2x(bitmask: u64) -> v128 {
const BITS: v128 = u64x2(1, 2);
i64x2_eq(v128_and(u64x2_splat(bitmask), BITS), BITS)
}
#[inline(always)]
pub fn bitmask_to_i16x8x(bitmask: u64) -> v128 {
const BITS: v128 = u16x8(1, 2, 4, 8, 16, 32, 64, 128);
i16x8_eq(v128_and(u16x8_splat(bitmask as u16), BITS), BITS)
}
#[inline(always)]
pub fn bitmask_to_i8x16x(bitmask: u64) -> v128 {
#[rustfmt::skip]
const BITS: v128 = u8x16(
1, 2, 4, 8, 16, 32, 64, 128,
1, 2, 4, 8, 16, 32, 64, 128,
);
const SPREAD: u64 = 0x0101_0101_0101_0101;
let lo = (bitmask & 0xFF) * SPREAD;
let hi = ((bitmask >> 8) & 0xFF) * SPREAD;
i8x16_eq(v128_and(u64x2(lo, hi), BITS), BITS)
}