macros.rs - source
Description: Source of the Rust file `library/core/src/../../stdarch/crates/core_arch/src/macros.rs`.

#
core/stdarch/crates/core_arch/src/
macros.rs

    1//! Utility macros.
    2
    3#[allow(unused)]
    4macro_rules! static_assert {
    5    ($e:expr) => {
    6        const {
    7            assert!($e);
    8        }
    9    };
    10    ($e:expr, $msg:expr) => {
    11        const {
    12            assert!($e, $msg);
    13        }
    14    };
    15}
    16
    17#[allow(unused_macros)]
    18macro_rules! static_assert_uimm_bits {
    19    ($imm:ident, $bits:expr) => {
    20        // `0 <= $imm` produces a warning if the immediate has an unsigned type
    21        #[allow(unused_comparisons)]
    22        {
    23            static_assert!(
    24                0 <= $imm && $imm < (1 << $bits),
    25                concat!(
    26                    stringify!($imm),
    27                    " doesn't fit in ",
    28                    stringify!($bits),
    29                    " bits",
    30                )
    31            )
    32        }
    33    };
    34}
    35
    36#[allow(unused_macros)]
    37macro_rules! static_assert_simm_bits {
    38    ($imm:ident, $bits:expr) => {
    39        static_assert!(
    40            (-1 << ($bits - 1)) - 1 <= $imm && $imm < (1 << ($bits - 1)),
    41            concat!(
    42                stringify!($imm),
    43                " doesn't fit in ",
    44                stringify!($bits),
    45                " bits",
    46            )
    47        )
    48    };
    49}
    50
    51#[allow(unused)]
    52macro_rules! types {
    53    (
    54        #![$stability_first:meta]
    55        $(
    56            #![$stability_more:meta]
    57        )*
    58
    59        $(
    60            $(#[$doc:meta])*
    61            $(stability: [$stability_already: meta])*
    62            pub struct $name:ident($len:literal x $v:vis $elem_type:ty);
    63        )*
    64    ) => (types! {
    65        $(
    66            #![$stability_more]
    67        )*
    68
    69        $(
    70            $(#[$doc])*
    71            $(stability: [$stability_already])*
    72            stability: [$stability_first]
    73            pub struct $name($len x $v $elem_type);
    74        )*
    75    });
    76
    77    (
    78        $(
    79            $(#[$doc:meta])*
    80            $(stability: [$stability: meta])+
    81            pub struct $name:ident($len:literal x $v:vis $elem_type:ty);
    82        )*
    83    ) => ($(
    84        $(#[$doc])*
    85        $(#[$stability])+
    86        #[derive(Copy, Clone)]
    87        #[allow(non_camel_case_types)]
    88        #[repr(simd)]
    89        #[allow(clippy::missing_inline_in_public_items)]
    90        pub struct $name($v [$elem_type; $len]);
    91
    92        impl $name {
    93            /// Using `my_simd([x; N])` seemingly fails tests,
    94            /// so use this internal helper for it instead.
    95            #[inline(always)]
    96            $v fn splat(value: $elem_type) -> $name {
    97                #[derive(Copy, Clone)]
    98                #[repr(simd)]
    99                struct JustOne([$elem_type; 1]);
    100                let one = JustOne([value]);
    101                // SAFETY: 0 is always in-bounds because we're shuffling
    102                // a simd type with exactly one element.
    103                unsafe { simd_shuffle!(one, one, [0; $len]) }
    104            }
    105
    106            /// Returns an array reference containing the entire SIMD vector.
    107            $v const fn as_array(&self) -> &[$elem_type; $len] {
    108                // SAFETY: this type is just an overaligned `[T; N]` with
    109                // potential padding at the end, so pointer casting to a
    110                // `&[T; N]` is safe.
    111                //
    112                // NOTE: This deliberately doesn't just use `&self.0` because it may soon be banned
    113                // see https://github.com/rust-lang/compiler-team/issues/838
    114                unsafe { &*(self as *const Self as *const [$elem_type; $len]) }
    115
    116            }
    117
    118            /// Returns a mutable array reference containing the entire SIMD vector.
    119            #[inline]
    120            $v fn as_mut_array(&mut self) -> &mut [$elem_type; $len] {
    121                // SAFETY: this type is just an overaligned `[T; N]` with
    122                // potential padding at the end, so pointer casting to a
    123                // `&mut [T; N]` is safe.
    124                //
    125                // NOTE: This deliberately doesn't just use `&mut self.0` because it may soon be banned
    126                // see https://github.com/rust-lang/compiler-team/issues/838
    127                unsafe { &mut *(self as *mut Self as *mut [$elem_type; $len]) }
    128            }
    129        }
    130
    131        $(#[$stability])+
    132        impl crate::fmt::Debug for $name {
    133            #[inline]
    134            fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
    135                crate::core_arch::simd::debug_simd_finish(f, stringify!($name), self.as_array())
    136            }
    137        }
    138    )*);
    139}
    140
    141#[allow(unused)]
    142#[repr(simd)]
    143pub(crate) struct SimdShuffleIdx<const LEN: usize>(pub(crate) [u32; LEN]);
    144
    145#[allow(unused)]
    146macro_rules! simd_shuffle {
    147    ($x:expr, $y:expr, $idx:expr $(,)?) => {{
    148        $crate::intrinsics::simd::simd_shuffle(
    149            $x,
    150            $y,
    151            const { $crate::core_arch::macros::SimdShuffleIdx($idx) },
    152        )
    153    }};
    154}
    155
    156#[allow(unused)]
    157macro_rules! simd_insert {
    158    ($x:expr, $idx:expr, $val:expr $(,)?) => {{ $crate::intrinsics::simd::simd_insert($x, const { $idx }, $val) }};
    159}
    160
    161#[allow(unused)]
    162macro_rules! simd_extract {
    163    ($x:expr, $idx:expr $(,)?) => {{ $crate::intrinsics::simd::simd_extract($x, const { $idx }) }};
    164    ($x:expr, $idx:expr, $ty:ty $(,)?) => {{ $crate::intrinsics::simd::simd_extract::<_, $ty>($x, const { $idx }) }};
    165}
    166
    167#[allow(unused)]
    168macro_rules! simd_masked_load {
    169    ($align:expr, $mask:expr, $ptr:expr, $default:expr) => {
    170        $crate::intrinsics::simd::simd_masked_load::<_, _, _, { $align }>($mask, $ptr, $default)
    171    };
    172}
    173
    174#[allow(unused)]
    175macro_rules! simd_masked_store {
    176    ($align:expr, $mask:expr, $ptr:expr, $default:expr) => {
    177        $crate::intrinsics::simd::simd_masked_store::<_, _, _, { $align }>($mask, $ptr, $default)
    178    };
    179}