#![allow(dead_code)]
use std::ops;
use std::mem;
#[allow(unused_imports)]
use super::{
Simd,
u32x4, i32x4, u16x8, i16x8, u8x16, i8x16, f32x4,
bool32ix4, bool16ix8, bool8ix16, bool32fx4,
simd_eq, simd_ne, simd_lt, simd_le, simd_gt, simd_ge,
simd_shuffle2, simd_shuffle4, simd_shuffle8, simd_shuffle16,
simd_insert, simd_extract,
simd_cast,
simd_add, simd_sub, simd_mul, simd_div, simd_shl, simd_shr, simd_and, simd_or, simd_xor,
bool8i, bool16i, bool32i, bool32f,
Unalign, bitcast,
};
use super::sixty_four::*;
#[cfg(all(target_feature = "avx"))]
use super::x86::avx::common;
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct u64x4(u64, u64, u64, u64);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct i64x4(i64, i64, i64, i64);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct f64x4(f64, f64, f64, f64);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool64ix4(i64, i64, i64, i64);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool64fx4(i64, i64, i64, i64);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct u32x8(u32, u32, u32, u32,
u32, u32, u32, u32);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct i32x8(i32, i32, i32, i32,
i32, i32, i32, i32);
#[repr(simd)]
#[cfg_attr(feature = "serde", derfve(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct f32x8(f32, f32, f32, f32,
f32, f32, f32, f32);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool32ix8(i32, i32, i32, i32,
i32, i32, i32, i32);#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool32fx8(i32, i32, i32, i32,
i32, i32, i32, i32);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct u16x16(u16, u16, u16, u16, u16, u16, u16, u16,
u16, u16, u16, u16, u16, u16, u16, u16);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct i16x16(i16, i16, i16, i16, i16, i16, i16, i16,
i16, i16, i16, i16, i16, i16, i16, i16);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool16ix16(i16, i16, i16, i16, i16, i16, i16, i16,
i16, i16, i16, i16, i16, i16, i16, i16);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct u8x32(u8, u8, u8, u8, u8, u8, u8, u8,
u8, u8, u8, u8, u8, u8, u8, u8,
u8, u8, u8, u8, u8, u8, u8, u8,
u8, u8, u8, u8, u8, u8, u8, u8);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct i8x32(i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8);
#[repr(simd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy)]
pub struct bool8ix32(i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8,
i8, i8, i8, i8, i8, i8, i8, i8);
simd! {
bool8ix32: i8x32 = i8, u8x32 = u8, bool8ix32 = bool8i;
bool16ix16: i16x16 = i16, u16x16 = u16, bool16ix16 = bool16i;
bool32ix8: i32x8 = i32, u32x8 = u32, bool32ix8 = bool32i;
bool64ix4: i64x4 = i64, u64x4 = u64, bool64ix4 = bool64i;
bool32fx8: f32x8 = f32, bool32fx8 = bool32f;
bool64fx4: f64x4 = f64, bool64fx4 = bool64f;
}
basic_impls! {
u64x4: u64, bool64ix4, simd_shuffle4, 4, x0, x1 | x2, x3;
i64x4: i64, bool64ix4, simd_shuffle4, 4, x0, x1 | x2, x3;
f64x4: f64, bool64fx4, simd_shuffle4, 4, x0, x1 | x2, x3;
u32x8: u32, bool32ix8, simd_shuffle8, 8, x0, x1, x2, x3 | x4, x5, x6, x7;
i32x8: i32, bool32ix8, simd_shuffle8, 8, x0, x1, x2, x3 | x4, x5, x6, x7;
f32x8: f32, bool32fx8, simd_shuffle8, 8, x0, x1, x2, x3 | x4, x5, x6, x7;
u16x16: u16, bool16ix16, simd_shuffle16, 16, x0, x1, x2, x3, x4, x5, x6, x7 | x8, x9, x10, x11, x12, x13, x14, x15;
i16x16: i16, bool16ix16, simd_shuffle16, 16, x0, x1, x2, x3, x4, x5, x6, x7 | x8, x9, x10, x11, x12, x13, x14, x15;
u8x32: u8, bool8ix32, simd_shuffle32, 32, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 |
x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31;
i8x32: i8, bool8ix32, simd_shuffle32, 32, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 |
x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31;
}
#[cfg(all(not(target_feature = "avx")))]
#[doc(hidden)]
mod common {
use super::*;
macro_rules! bools {
($($ty: ty, $all: ident, $any: ident;)*) => {
$(
#[inline]
pub fn $all(x: $ty) -> bool {
x.low().all() && x.high().all()
}
#[inline]
pub fn $any(x: $ty) -> bool {
x.low().any() || x.high().any()
}
)*
}
}
bools! {
bool64ix4, bool64ix4_all, bool64ix4_any;
bool64fx4, bool64fx4_all, bool64fx4_any;
bool32ix8, bool32ix8_all, bool32ix8_any;
bool32fx8, bool32fx8_all, bool32fx8_any;
bool16ix16, bool16ix16_all, bool16ix16_any;
bool8ix32, bool8ix32_all, bool8ix32_any;
}
}
bool_impls! {
bool64ix4: bool64i, i64x4, i64, 4, bool64ix4_all, bool64ix4_any, x0, x1 | x2, x3
[ to_f -> bool64fx4];
bool64fx4: bool64f, i64x4, i64, 4, bool64fx4_all, bool64fx4_any, x0, x1 | x2, x3
[ to_i -> bool64ix4];
bool32ix8: bool32i, i32x8, i32, 8, bool32ix8_all, bool32ix8_any, x0, x1, x2, x3 | x4, x5, x6, x7
[ to_f -> bool32fx8];
bool32fx8: bool32f, i32x8, i32, 8, bool32fx8_all, bool32fx8_any, x0, x1, x2, x3 | x4, x5, x6, x7
[ to_i -> bool32ix8];
bool16ix16: bool16i, i16x16, i16, 16, bool16ix16_all, bool16ix16_any,
x0, x1, x2, x3, x4, x5, x6, x7 | x8, x9, x10, x11, x12, x13, x14, x15 [];
bool8ix32: bool8i, i8x32, i8, 32, bool8ix32_all, bool8ix32_any,
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 |
x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 [];
}
pub trait LowHigh128 {
type Half: Simd;
fn low(self) -> Self::Half;
fn high(self) -> Self::Half;
}
macro_rules! expr { ($x:expr) => ($x) } macro_rules! low_high_impls {
($(
$name: ident, $half: ident, $($first: tt),+ ... $($last: tt),+;
)*) => {
$(impl LowHigh128 for $name {
type Half = $half;
#[inline]
fn low(self) -> Self::Half {
$half::new($( expr!(self.$first), )*)
}
#[inline]
fn high(self) -> Self::Half {
$half::new($( expr!(self.$last), )*)
}
})*
}
}
low_high_impls! {
u64x4, u64x2, 0, 1 ... 2, 3;
i64x4, i64x2, 0, 1 ... 2, 3;
f64x4, f64x2, 0, 1 ... 2, 3;
u32x8, u32x4, 0, 1, 2, 3 ... 4, 5, 6, 7;
i32x8, i32x4, 0, 1, 2, 3 ... 4, 5, 6, 7;
f32x8, f32x4, 0, 1, 2, 3 ... 4, 5, 6, 7;
u16x16, u16x8, 0, 1, 2, 3, 4, 5, 6, 7 ... 8, 9, 10, 11, 12, 13, 14, 15;
i16x16, i16x8, 0, 1, 2, 3, 4, 5, 6, 7 ... 8, 9, 10, 11, 12, 13, 14, 15;
u8x32, u8x16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ...
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31;
i8x32, i8x16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ...
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31;
}
macro_rules! bool_low_high_impls {
($(
$name: ident: $half: ident;
)*) => {
$(impl LowHigh128 for $name {
type Half = $half;
#[inline]
fn low(self) -> Self::Half {
Self::Half::from_repr(self.to_repr().low())
}
#[inline]
fn high(self) -> Self::Half {
Self::Half::from_repr(self.to_repr().high())
}
})*
}
}
bool_low_high_impls! {
bool64fx4: bool64fx2;
bool32fx8: bool32fx4;
bool64ix4: bool64ix2;
bool32ix8: bool32ix4;
bool16ix16: bool16ix8;
bool8ix32: bool8ix16;
}
impl u64x4 {
#[inline]
pub fn to_i64(self) -> i64x4 {
unsafe {simd_cast(self)}
}
#[inline]
pub fn to_f64(self) -> f64x4 {
unsafe {simd_cast(self)}
}
}
impl i64x4 {
#[inline]
pub fn to_u64(self) -> u64x4 {
unsafe {simd_cast(self)}
}
#[inline]
pub fn to_f64(self) -> f64x4 {
unsafe {simd_cast(self)}
}
}
impl f64x4 {
#[inline]
pub fn to_i64(self) -> i64x4 {
unsafe {simd_cast(self)}
}
#[inline]
pub fn to_u64(self) -> u64x4 {
unsafe {simd_cast(self)}
}
}
impl u32x8 {
#[inline]
pub fn to_i32(self) -> i32x8 {
unsafe {simd_cast(self)}
}
#[inline]
pub fn to_f32(self) -> f32x8 {
unsafe {simd_cast(self)}
}
}
impl i32x8 {
#[inline]
pub fn to_u32(self) -> u32x8 {
unsafe {simd_cast(self)}
}
#[inline]
pub fn to_f32(self) -> f32x8 {
unsafe {simd_cast(self)}
}
}
impl i16x16 {
#[inline]
pub fn to_u16(self) -> u16x16 {
unsafe {simd_cast(self)}
}
}
impl u16x16 {
#[inline]
pub fn to_i16(self) -> i16x16 {
unsafe {simd_cast(self)}
}
}
impl i8x32 {
#[inline]
pub fn to_u8(self) -> u8x32 {
unsafe {simd_cast(self)}
}
}
impl u8x32 {
#[inline]
pub fn to_i8(self) -> i8x32 {
unsafe {simd_cast(self)}
}
}
operators! {
Add (simd_add, add):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
f64x4, f32x8;
Sub (simd_sub, sub):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
f64x4, f32x8;
Mul (simd_mul, mul):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
f64x4, f32x8;
Div (simd_div, div): f64x4, f32x8;
BitAnd (simd_and, bitand):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
bool64ix4, bool32ix8, bool16ix16,
bool64fx4, bool32fx8;
BitOr (simd_or, bitor):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
bool64ix4, bool32ix8, bool16ix16,
bool64fx4, bool32fx8;
BitXor (simd_xor, bitxor):
i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, i64x4, u64x4,
bool64ix4, bool32ix8, bool16ix16,
bool64fx4, bool32fx8;
}
neg_impls!{
0,
i64x4,
i32x8,
i16x16,
i8x32,
}
neg_impls! {
0.0,
f64x4,
f32x8,
}
not_impls! {
i64x4,
u64x4,
i32x8,
u32x8,
i16x16,
u16x16,
i8x32,
u8x32,
}
shift! {
i64x4,
u64x4,
i32x8,
u32x8,
i16x16,
u16x16,
i8x32,
u8x32
}