Add masks
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/// Provides implementations of `From<$a> for $b` and `From<$b> for $a` that transmutes the value.
|
||||
macro_rules! from_transmute {
|
||||
{ unsafe $a:ty => $b:ty } => {
|
||||
from_transmute!{ @impl $a => $b }
|
||||
@@ -13,6 +14,8 @@ macro_rules! from_transmute {
|
||||
};
|
||||
}
|
||||
|
||||
/// Provides implementations of `From<$generic> for core::arch::{x86, x86_64}::$intel` and
|
||||
/// vice-versa that transmutes the value.
|
||||
macro_rules! from_transmute_x86 {
|
||||
{ unsafe $generic:ty => $intel:ident } => {
|
||||
#[cfg(target_arch = "x86")]
|
||||
@@ -23,10 +26,118 @@ macro_rules! from_transmute_x86 {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_type {
|
||||
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
|
||||
define_type! { @impl $(#[$attr])* | $name [$type; $lanes] }
|
||||
/// Calls a the macro `$mac` with the provided `$args` followed by `$repeat` repeated the specified
|
||||
/// number of times.
|
||||
macro_rules! call_repeat {
|
||||
{ 1 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)*
|
||||
}
|
||||
};
|
||||
{ 2 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
{ 4 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
{ 8 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
{ 16 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
{ 32 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
{ 64 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
$($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Calls the macro `$mac` with the specified `$args` followed by the specified number of unique
|
||||
/// identifiers.
|
||||
macro_rules! call_counting_args {
|
||||
{ 1 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
value
|
||||
}
|
||||
};
|
||||
{ 2 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
v1 v2
|
||||
}
|
||||
};
|
||||
{ 4 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
v0 v1 v2 v3
|
||||
}
|
||||
};
|
||||
{ 8 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
v0 v1 v2 v3 v4 v5 v6 v7
|
||||
}
|
||||
};
|
||||
{ 16 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
|
||||
}
|
||||
};
|
||||
{ 32 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
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
|
||||
}
|
||||
};
|
||||
{ 64 => $mac:path => $($args:tt)* } => {
|
||||
$mac! {
|
||||
$($args)*
|
||||
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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
|
||||
macro_rules! base_vector_traits {
|
||||
{ $name:path => [$type:ty; $lanes:literal] } => {
|
||||
// array references
|
||||
impl AsRef<[$type; $lanes]> for $name {
|
||||
#[inline]
|
||||
@@ -67,71 +178,78 @@ macro_rules! define_type {
|
||||
Self::splat(value)
|
||||
}
|
||||
}
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 1] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $type | $type, | v0, }
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 2] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $type | $type, $type, | v0, v1, }
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 4] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $type |
|
||||
$type, $type, $type, $type, |
|
||||
v0, v1, v2, v3,
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a vector `$name` containing multiple `$lanes` of `$type`.
|
||||
macro_rules! define_vector {
|
||||
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
|
||||
call_repeat! { $lanes => define_vector [$type] def $(#[$attr])* | $name | }
|
||||
|
||||
impl $name {
|
||||
call_repeat! { $lanes => define_vector [$type] splat $type | }
|
||||
call_counting_args! { $lanes => define_vector => new $type | }
|
||||
}
|
||||
|
||||
base_vector_traits! { $name => [$type; $lanes] }
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 8] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $type |
|
||||
$type, $type, $type, $type, $type, $type, $type, $type, |
|
||||
v0, v1, v2, v3, v4, v5, v6, v7,
|
||||
}
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 16] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $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,
|
||||
}
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 32] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $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,
|
||||
}
|
||||
};
|
||||
{ @impl $(#[$attr:meta])* | $name:ident [$type:ty; 64] } => {
|
||||
define_type! { @def $(#[$attr])* | $name | $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, $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,
|
||||
}
|
||||
};
|
||||
{ @def $(#[$attr:meta])* | $name:ident | $type:ty | $($itype:ty,)* | $($ivar:ident,)* } => {
|
||||
{ def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
|
||||
$(#[$attr])*
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
|
||||
#[repr(simd)]
|
||||
pub struct $name($($itype),*);
|
||||
|
||||
impl $name {
|
||||
/// Construct a vector by setting all lanes to the given value.
|
||||
#[inline]
|
||||
pub const fn splat(value: $type) -> Self {
|
||||
Self($(value as $itype),*)
|
||||
}
|
||||
|
||||
/// Construct a vector by setting each lane to the given values.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[inline]
|
||||
pub const fn new($($ivar: $itype),*) -> Self {
|
||||
Self($($ivar),*)
|
||||
}
|
||||
};
|
||||
{ splat $type:ty | $($itype:ty)* } => {
|
||||
/// Construct a vector by setting all lanes to the given value.
|
||||
#[inline]
|
||||
pub const fn splat(value: $type) -> Self {
|
||||
Self($(value as $itype),*)
|
||||
}
|
||||
};
|
||||
{ new $type:ty | $($var:ident)* } => {
|
||||
/// Construct a vector by setting each lane to the given values.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[inline]
|
||||
pub const fn new($($var: $type),*) -> Self {
|
||||
Self($($var),*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a mask vector `$name` containing multiple `$lanes` of `$type`, represented by the
|
||||
/// underlying type `$impl_type`.
|
||||
macro_rules! define_mask_vector {
|
||||
{ $(#[$attr:meta])* struct $name:ident([$impl_type:ty as $type:ty; $lanes:tt]); } => {
|
||||
call_repeat! { $lanes => define_mask_vector [$impl_type] def $(#[$attr])* | $name | }
|
||||
|
||||
impl $name {
|
||||
call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | }
|
||||
call_counting_args! { $lanes => define_mask_vector => new $type | }
|
||||
}
|
||||
|
||||
base_vector_traits! { $name => [$type; $lanes] }
|
||||
};
|
||||
{ def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
|
||||
$(#[$attr])*
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
|
||||
#[repr(simd)]
|
||||
pub struct $name($($itype),*);
|
||||
};
|
||||
{ splat $type:ty | $($itype:ty)* } => {
|
||||
/// Construct a vector by setting all lanes to the given value.
|
||||
#[inline]
|
||||
pub const fn splat(value: $type) -> Self {
|
||||
Self($(value.0 as $itype),*)
|
||||
}
|
||||
};
|
||||
{ new $type:ty | $($var:ident)* } => {
|
||||
/// Construct a vector by setting each lane to the given values.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[inline]
|
||||
pub const fn new($($var: $type),*) -> Self {
|
||||
Self($($var.0),*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user