1 /// Provides implementations of `From<$a> for $b` and `From<$b> for $a` that transmutes the value.
2 macro_rules! from_transmute {
3 { unsafe $a:ty => $b:ty } => {
4 from_transmute!{ @impl $a => $b }
5 from_transmute!{ @impl $b => $a }
7 { @impl $from:ty => $to:ty } => {
8 impl core::convert::From<$from> for $to {
10 fn from(value: $from) -> $to {
11 unsafe { core::mem::transmute(value) }
17 /// Provides implementations of `From<$generic> for core::arch::{x86, x86_64}::$intel` and
18 /// vice-versa that transmutes the value.
19 macro_rules! from_transmute_x86 {
20 { unsafe $generic:ty => $intel:ident } => {
21 #[cfg(target_arch = "x86")]
22 from_transmute! { unsafe $generic => core::arch::x86::$intel }
24 #[cfg(target_arch = "x86_64")]
25 from_transmute! { unsafe $generic => core::arch::x86_64::$intel }
29 /// Calls a the macro `$mac` with the provided `$args` followed by `$repeat` repeated the specified
31 macro_rules! call_repeat {
32 { 1 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
38 { 2 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
41 $($repeat)* $($repeat)*
44 { 4 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
47 $($repeat)* $($repeat)* $($repeat)* $($repeat)*
50 { 8 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
53 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
56 { 16 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
59 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
60 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
63 { 32 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
66 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
67 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
68 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
69 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
72 { 64 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
75 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
76 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
77 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
78 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
79 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
80 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
81 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
82 $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
87 /// Calls the macro `$mac` with the specified `$args` followed by the specified number of unique
89 macro_rules! call_counting_args {
90 { 1 => $mac:path => $($args:tt)* } => {
96 { 2 => $mac:path => $($args:tt)* } => {
102 { 4 => $mac:path => $($args:tt)* } => {
108 { 8 => $mac:path => $($args:tt)* } => {
111 v0 v1 v2 v3 v4 v5 v6 v7
114 { 16 => $mac:path => $($args:tt)* } => {
117 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
120 { 32 => $mac:path => $($args:tt)* } => {
123 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
124 v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29 v30 v31
127 { 64 => $mac:path => $($args:tt)* } => {
130 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
131 v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29 v30 v31
132 v32 v33 v34 v35 v36 v37 v38 v39 v40 v41 v42 v43 v44 v45 v46 v47
133 v48 v49 v50 v51 v52 v53 v54 v55 v56 v57 v58 v59 v60 v61 v62 v63
138 /// Calls the macro `$mac` with the specified `$args` followed by counting values from 0 to the
140 macro_rules! call_counting_values {
141 { 1 => $mac:path => $($args:tt)* } => {
147 { 2 => $mac:path => $($args:tt)* } => {
153 { 4 => $mac:path => $($args:tt)* } => {
159 { 8 => $mac:path => $($args:tt)* } => {
165 { 16 => $mac:path => $($args:tt)* } => {
168 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
171 { 32 => $mac:path => $($args:tt)* } => {
174 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
175 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
178 { 64 => $mac:path => $($args:tt)* } => {
181 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
182 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
183 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
184 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
189 /// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
190 macro_rules! base_vector_traits {
191 { $name:path => [$type:ty; $lanes:literal] } => {
193 impl AsRef<[$type; $lanes]> for $name {
195 fn as_ref(&self) -> &[$type; $lanes] {
196 unsafe { &*(self as *const _ as *const _) }
200 impl AsMut<[$type; $lanes]> for $name {
202 fn as_mut(&mut self) -> &mut [$type; $lanes] {
203 unsafe { &mut *(self as *mut _ as *mut _) }
208 impl AsRef<[$type]> for $name {
210 fn as_ref(&self) -> &[$type] {
211 AsRef::<[$type; $lanes]>::as_ref(self)
215 impl AsMut<[$type]> for $name {
217 fn as_mut(&mut self) -> &mut [$type] {
218 AsMut::<[$type; $lanes]>::as_mut(self)
222 // vector/array conversion
223 from_transmute! { unsafe $name => [$type; $lanes] }
226 impl From<$type> for $name {
228 fn from(value: $type) -> Self {
235 /// Defines a vector `$name` containing multiple `$lanes` of `$type`.
236 macro_rules! define_vector {
237 { $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
238 call_repeat! { $lanes => define_vector [$type] def $(#[$attr])* | $name | }
241 call_repeat! { $lanes => define_vector [$type] splat $type | }
242 call_counting_args! { $lanes => define_vector => new $type | }
245 base_vector_traits! { $name => [$type; $lanes] }
247 { def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
249 #[allow(non_camel_case_types)]
250 #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
252 pub struct $name($($itype),*);
254 { splat $type:ty | $($itype:ty)* } => {
255 /// Construct a vector by setting all lanes to the given value.
257 pub const fn splat(value: $type) -> Self {
258 Self($(value as $itype),*)
261 { new $type:ty | $($var:ident)* } => {
262 /// Construct a vector by setting each lane to the given values.
263 #[allow(clippy::too_many_arguments)]
265 pub const fn new($($var: $type),*) -> Self {
271 /// Defines a mask vector `$name` containing multiple `$lanes` of `$type`, represented by the
272 /// underlying type `$impl_type`.
273 macro_rules! define_mask_vector {
274 { $(#[$attr:meta])* struct $name:ident([$impl_type:ty as $type:ty; $lanes:tt]); } => {
275 call_repeat! { $lanes => define_mask_vector [$impl_type] def $(#[$attr])* | $name | }
278 call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | }
279 call_counting_args! { $lanes => define_mask_vector => new $type | }
282 base_vector_traits! { $name => [$type; $lanes] }
284 { def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
286 #[allow(non_camel_case_types)]
287 #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Eq, Ord)]
289 pub struct $name($($itype),*);
291 { splat $type:ty | $($itype:ty)* } => {
292 /// Construct a vector by setting all lanes to the given value.
294 pub const fn splat(value: $type) -> Self {
295 Self($(value.0 as $itype),*)
298 { new $type:ty | $($var:ident)* } => {
299 /// Construct a vector by setting each lane to the given values.
300 #[allow(clippy::too_many_arguments)]
302 pub const fn new($($var: $type),*) -> Self {