2020-09-23 10:42:12 -04:00
|
|
|
macro_rules! from_transmute {
|
|
|
|
|
{ unsafe $a:ty => $b:ty } => {
|
|
|
|
|
from_transmute!{ @impl $a => $b }
|
|
|
|
|
from_transmute!{ @impl $b => $a }
|
|
|
|
|
};
|
|
|
|
|
{ @impl $from:ty => $to:ty } => {
|
2020-09-22 19:41:42 -04:00
|
|
|
impl core::convert::From<$from> for $to {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from(value: $from) -> $to {
|
|
|
|
|
unsafe { core::mem::transmute(value) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-23 10:42:12 -04:00
|
|
|
macro_rules! from_transmute_x86 {
|
|
|
|
|
{ unsafe $generic:ty => $intel:ident } => {
|
|
|
|
|
#[cfg(target_arch = "x86")]
|
|
|
|
|
from_transmute! { unsafe $generic => core::arch::x86::$intel }
|
|
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
|
from_transmute! { unsafe $generic => core::arch::x86_64::$intel }
|
2020-09-22 19:41:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! define_type {
|
2020-09-22 20:26:25 -04:00
|
|
|
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
|
|
|
|
|
define_type! { @impl $(#[$attr])* | $name [$type; $lanes] }
|
2020-09-22 19:41:42 -04:00
|
|
|
|
|
|
|
|
// array references
|
|
|
|
|
impl AsRef<[$type; $lanes]> for $name {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_ref(&self) -> &[$type; $lanes] {
|
|
|
|
|
unsafe { &*(self as *const _ as *const _) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsMut<[$type; $lanes]> for $name {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_mut(&mut self) -> &mut [$type; $lanes] {
|
|
|
|
|
unsafe { &mut *(self as *mut _ as *mut _) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// slice references
|
|
|
|
|
impl AsRef<[$type]> for $name {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_ref(&self) -> &[$type] {
|
|
|
|
|
AsRef::<[$type; $lanes]>::as_ref(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsMut<[$type]> for $name {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_mut(&mut self) -> &mut [$type] {
|
|
|
|
|
AsMut::<[$type; $lanes]>::as_mut(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-23 10:42:12 -04:00
|
|
|
// vector/array conversion
|
|
|
|
|
from_transmute! { unsafe $name => [$type; $lanes] }
|
2020-09-22 19:41:42 -04:00
|
|
|
|
|
|
|
|
// splat
|
|
|
|
|
impl From<$type> for $name {
|
2020-09-23 08:11:43 -04:00
|
|
|
#[inline]
|
2020-09-22 19:41:42 -04:00
|
|
|
fn from(value: $type) -> Self {
|
|
|
|
|
Self::splat(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 1] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type | $type, | v0, }
|
2020-09-22 19:41:42 -04:00
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 2] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type | $type, $type, | v0, v1, }
|
2020-09-22 19:41:42 -04:00
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 4] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type |
|
2020-09-22 19:41:42 -04:00
|
|
|
$type, $type, $type, $type, |
|
|
|
|
|
v0, v1, v2, v3,
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 8] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type |
|
2020-09-22 19:41:42 -04:00
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, |
|
|
|
|
|
v0, v1, v2, v3, v4, v5, v6, v7,
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 16] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type |
|
2020-09-22 19:41:42 -04:00
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
|
|
|
|
|
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 32] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type |
|
2020-09-22 19:41:42 -04:00
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
|
|
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
|
|
|
|
|
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
|
|
|
|
|
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 64] } => {
|
|
|
|
|
define_type! { @def $(#[$attr])* | $name | $type |
|
2020-09-22 19:41:42 -04:00
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
|
|
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
|
|
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
|
|
|
|
|
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
|
|
|
|
|
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
|
|
|
|
|
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
|
|
|
|
|
v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
|
|
|
|
|
v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63,
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-09-22 20:26:25 -04:00
|
|
|
{ @def $(#[$attr:meta])* | $name:ident | $type:ty | $($itype:ty,)* | $($ivar:ident,)* } => {
|
|
|
|
|
$(#[$attr])*
|
2020-09-22 19:41:42 -04:00
|
|
|
#[allow(non_camel_case_types)]
|
|
|
|
|
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
|
|
|
|
|
#[repr(simd)]
|
|
|
|
|
pub struct $name($($itype),*);
|
|
|
|
|
|
|
|
|
|
impl $name {
|
2020-09-23 08:11:43 -04:00
|
|
|
/// Construct a vector by setting all lanes to the given value.
|
2020-09-22 19:41:42 -04:00
|
|
|
#[inline]
|
2020-09-23 08:11:43 -04:00
|
|
|
pub const fn splat(value: $type) -> Self {
|
2020-09-22 19:41:42 -04:00
|
|
|
Self($(value as $itype),*)
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-23 08:11:43 -04:00
|
|
|
/// Construct a vector by setting each lane to the given values.
|
2020-09-22 19:41:42 -04:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
|
|
#[inline]
|
2020-09-23 08:11:43 -04:00
|
|
|
pub const fn new($($ivar: $itype),*) -> Self {
|
2020-09-22 19:41:42 -04:00
|
|
|
Self($($ivar),*)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|