#
core/stdarch/crates/core_arch/src/x86/
mod.rs

    1//! `x86` and `x86_64` intrinsics.
    2
    3use crate::mem::transmute;
    4
    5#[macro_use]
    6mod macros;
    7
    8types! {
    9    #![stable(feature = "simd_x86", since = "1.27.0")]
    10
    11    /// 128-bit wide integer vector type, x86-specific
    12    ///
    13    /// This type is the same as the `__m128i` type defined by Intel,
    14    /// representing a 128-bit SIMD register. Usage of this type typically
    15    /// corresponds to the `sse` and up target features for x86/x86_64.
    16    ///
    17    /// Internally this type may be viewed as:
    18    ///
    19    /// * `i8x16` - sixteen `i8` variables packed together
    20    /// * `i16x8` - eight `i16` variables packed together
    21    /// * `i32x4` - four `i32` variables packed together
    22    /// * `i64x2` - two `i64` variables packed together
    23    ///
    24    /// (as well as unsigned versions). Each intrinsic may interpret the
    25    /// internal bits differently, check the documentation of the intrinsic
    26    /// to see how it's being used.
    27    ///
    28    /// The in-memory representation of this type is the same as the one of an
    29    /// equivalent array (i.e. the in-memory order of elements is the same, and
    30    /// there is no padding); however, the alignment is different and equal to
    31    /// the size of the type. Note that the ABI for function calls may *not* be
    32    /// the same.
    33    ///
    34    /// Note that this means that an instance of `__m128i` typically just means
    35    /// a "bag of bits" which is left up to interpretation at the point of use.
    36    ///
    37    /// Most intrinsics using `__m128i` are prefixed with `_mm_` and the
    38    /// integer types tend to correspond to suffixes like "epi8" or "epi32".
    39    ///
    40    /// # Examples
    41    ///
    42    /// ```
    43    /// #[cfg(target_arch = "x86")]
    44    /// use std::arch::x86::*;
    45    /// #[cfg(target_arch = "x86_64")]
    46    /// use std::arch::x86_64::*;
    47    ///
    48    /// # fn main() {
    49    /// # #[target_feature(enable = "sse2")]
    50    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    51    /// # unsafe fn foo() { unsafe {
    52    /// let all_bytes_zero = _mm_setzero_si128();
    53    /// let all_bytes_one = _mm_set1_epi8(1);
    54    /// let four_i32 = _mm_set_epi32(1, 2, 3, 4);
    55    /// # }}
    56    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
    57    /// # }
    58    /// ```
    59    pub struct __m128i(2 x i64);
    60
    61    /// 128-bit wide set of four `f32` types, x86-specific
    62    ///
    63    /// This type is the same as the `__m128` type defined by Intel,
    64    /// representing a 128-bit SIMD register which internally is consisted of
    65    /// four packed `f32` instances. Usage of this type typically corresponds
    66    /// to the `sse` and up target features for x86/x86_64.
    67    ///
    68    /// Note that unlike `__m128i`, the integer version of the 128-bit
    69    /// registers, this `__m128` type has *one* interpretation. Each instance
    70    /// of `__m128` always corresponds to `f32x4`, or four `f32` types packed
    71    /// together.
    72    ///
    73    /// The in-memory representation of this type is the same as the one of an
    74    /// equivalent array (i.e. the in-memory order of elements is the same, and
    75    /// there is no padding); however, the alignment is different and equal to
    76    /// the size of the type. Note that the ABI for function calls may *not* be
    77    /// the same.
    78    ///
    79    /// Most intrinsics using `__m128` are prefixed with `_mm_` and are
    80    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
    81    /// "pd" which is used for `__m128d`.
    82    ///
    83    /// # Examples
    84    ///
    85    /// ```
    86    /// #[cfg(target_arch = "x86")]
    87    /// use std::arch::x86::*;
    88    /// #[cfg(target_arch = "x86_64")]
    89    /// use std::arch::x86_64::*;
    90    ///
    91    /// # fn main() {
    92    /// # #[target_feature(enable = "sse")]
    93    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    94    /// # unsafe fn foo() { unsafe {
    95    /// let four_zeros = _mm_setzero_ps();
    96    /// let four_ones = _mm_set1_ps(1.0);
    97    /// let four_floats = _mm_set_ps(1.0, 2.0, 3.0, 4.0);
    98    /// # }}
    99    /// # if is_x86_feature_detected!("sse") { unsafe { foo() } }
    100    /// # }
    101    /// ```
    102    pub struct __m128(4 x f32);
    103
    104    /// 128-bit wide set of two `f64` types, x86-specific
    105    ///
    106    /// This type is the same as the `__m128d` type defined by Intel,
    107    /// representing a 128-bit SIMD register which internally is consisted of
    108    /// two packed `f64` instances. Usage of this type typically corresponds
    109    /// to the `sse` and up target features for x86/x86_64.
    110    ///
    111    /// Note that unlike `__m128i`, the integer version of the 128-bit
    112    /// registers, this `__m128d` type has *one* interpretation. Each instance
    113    /// of `__m128d` always corresponds to `f64x2`, or two `f64` types packed
    114    /// together.
    115    ///
    116    /// The in-memory representation of this type is the same as the one of an
    117    /// equivalent array (i.e. the in-memory order of elements is the same, and
    118    /// there is no padding); however, the alignment is different and equal to
    119    /// the size of the type. Note that the ABI for function calls may *not* be
    120    /// the same.
    121    ///
    122    /// Most intrinsics using `__m128d` are prefixed with `_mm_` and are
    123    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
    124    /// "ps" which is used for `__m128`.
    125    ///
    126    /// # Examples
    127    ///
    128    /// ```
    129    /// #[cfg(target_arch = "x86")]
    130    /// use std::arch::x86::*;
    131    /// #[cfg(target_arch = "x86_64")]
    132    /// use std::arch::x86_64::*;
    133    ///
    134    /// # fn main() {
    135    /// # #[target_feature(enable = "sse2")]
    136    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    137    /// # unsafe fn foo() { unsafe {
    138    /// let two_zeros = _mm_setzero_pd();
    139    /// let two_ones = _mm_set1_pd(1.0);
    140    /// let two_floats = _mm_set_pd(1.0, 2.0);
    141    /// # }}
    142    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
    143    /// # }
    144    /// ```
    145    pub struct __m128d(2 x f64);
    146
    147    /// 256-bit wide integer vector type, x86-specific
    148    ///
    149    /// This type is the same as the `__m256i` type defined by Intel,
    150    /// representing a 256-bit SIMD register. Usage of this type typically
    151    /// corresponds to the `avx` and up target features for x86/x86_64.
    152    ///
    153    /// Internally this type may be viewed as:
    154    ///
    155    /// * `i8x32` - thirty two `i8` variables packed together
    156    /// * `i16x16` - sixteen `i16` variables packed together
    157    /// * `i32x8` - eight `i32` variables packed together
    158    /// * `i64x4` - four `i64` variables packed together
    159    ///
    160    /// (as well as unsigned versions). Each intrinsic may interpret the
    161    /// internal bits differently, check the documentation of the intrinsic
    162    /// to see how it's being used.
    163    ///
    164    /// The in-memory representation of this type is the same as the one of an
    165    /// equivalent array (i.e. the in-memory order of elements is the same, and
    166    /// there is no padding); however, the alignment is different and equal to
    167    /// the size of the type. Note that the ABI for function calls may *not* be
    168    /// the same.
    169    ///
    170    /// Note that this means that an instance of `__m256i` typically just means
    171    /// a "bag of bits" which is left up to interpretation at the point of use.
    172    ///
    173    /// # Examples
    174    ///
    175    /// ```
    176    /// #[cfg(target_arch = "x86")]
    177    /// use std::arch::x86::*;
    178    /// #[cfg(target_arch = "x86_64")]
    179    /// use std::arch::x86_64::*;
    180    ///
    181    /// # fn main() {
    182    /// # #[target_feature(enable = "avx")]
    183    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    184    /// # unsafe fn foo() { unsafe {
    185    /// let all_bytes_zero = _mm256_setzero_si256();
    186    /// let all_bytes_one = _mm256_set1_epi8(1);
    187    /// let eight_i32 = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8);
    188    /// # }}
    189    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
    190    /// # }
    191    /// ```
    192    pub struct __m256i(4 x i64);
    193
    194    /// 256-bit wide set of eight `f32` types, x86-specific
    195    ///
    196    /// This type is the same as the `__m256` type defined by Intel,
    197    /// representing a 256-bit SIMD register which internally is consisted of
    198    /// eight packed `f32` instances. Usage of this type typically corresponds
    199    /// to the `avx` and up target features for x86/x86_64.
    200    ///
    201    /// Note that unlike `__m256i`, the integer version of the 256-bit
    202    /// registers, this `__m256` type has *one* interpretation. Each instance
    203    /// of `__m256` always corresponds to `f32x8`, or eight `f32` types packed
    204    /// together.
    205    ///
    206    /// The in-memory representation of this type is the same as the one of an
    207    /// equivalent array (i.e. the in-memory order of elements is the same, and
    208    /// there is no padding  between two consecutive elements); however, the
    209    /// alignment is different and equal to the size of the type. Note that the
    210    /// ABI for function calls may *not* be the same.
    211    ///
    212    /// Most intrinsics using `__m256` are prefixed with `_mm256_` and are
    213    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
    214    /// "pd" which is used for `__m256d`.
    215    ///
    216    /// # Examples
    217    ///
    218    /// ```
    219    /// #[cfg(target_arch = "x86")]
    220    /// use std::arch::x86::*;
    221    /// #[cfg(target_arch = "x86_64")]
    222    /// use std::arch::x86_64::*;
    223    ///
    224    /// # fn main() {
    225    /// # #[target_feature(enable = "avx")]
    226    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    227    /// # unsafe fn foo() { unsafe {
    228    /// let eight_zeros = _mm256_setzero_ps();
    229    /// let eight_ones = _mm256_set1_ps(1.0);
    230    /// let eight_floats = _mm256_set_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
    231    /// # }}
    232    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
    233    /// # }
    234    /// ```
    235    pub struct __m256(8 x f32);
    236
    237    /// 256-bit wide set of four `f64` types, x86-specific
    238    ///
    239    /// This type is the same as the `__m256d` type defined by Intel,
    240    /// representing a 256-bit SIMD register which internally is consisted of
    241    /// four packed `f64` instances. Usage of this type typically corresponds
    242    /// to the `avx` and up target features for x86/x86_64.
    243    ///
    244    /// Note that unlike `__m256i`, the integer version of the 256-bit
    245    /// registers, this `__m256d` type has *one* interpretation. Each instance
    246    /// of `__m256d` always corresponds to `f64x4`, or four `f64` types packed
    247    /// together.
    248    ///
    249    /// The in-memory representation of this type is the same as the one of an
    250    /// equivalent array (i.e. the in-memory order of elements is the same, and
    251    /// there is no padding); however, the alignment is different and equal to
    252    /// the size of the type. Note that the ABI for function calls may *not* be
    253    /// the same.
    254    ///
    255    /// Most intrinsics using `__m256d` are prefixed with `_mm256_` and are
    256    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
    257    /// "ps" which is used for `__m256`.
    258    ///
    259    /// # Examples
    260    ///
    261    /// ```
    262    /// #[cfg(target_arch = "x86")]
    263    /// use std::arch::x86::*;
    264    /// #[cfg(target_arch = "x86_64")]
    265    /// use std::arch::x86_64::*;
    266    ///
    267    /// # fn main() {
    268    /// # #[target_feature(enable = "avx")]
    269    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
    270    /// # unsafe fn foo() { unsafe {
    271    /// let four_zeros = _mm256_setzero_pd();
    272    /// let four_ones = _mm256_set1_pd(1.0);
    273    /// let four_floats = _mm256_set_pd(1.0, 2.0, 3.0, 4.0);
    274    /// # }}
    275    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
    276    /// # }
    277    /// ```
    278    pub struct __m256d(4 x f64);
    279}
    280
    281types! {
    282    #![stable(feature = "simd_avx512_types", since = "1.72.0")]
    283
    284    /// 512-bit wide integer vector type, x86-specific
    285    ///
    286    /// This type is the same as the `__m512i` type defined by Intel,
    287    /// representing a 512-bit SIMD register. Usage of this type typically
    288    /// corresponds to the `avx512*` and up target features for x86/x86_64.
    289    ///
    290    /// Internally this type may be viewed as:
    291    ///
    292    /// * `i8x64` - sixty-four `i8` variables packed together
    293    /// * `i16x32` - thirty-two `i16` variables packed together
    294    /// * `i32x16` - sixteen `i32` variables packed together
    295    /// * `i64x8` - eight `i64` variables packed together
    296    ///
    297    /// (as well as unsigned versions). Each intrinsic may interpret the
    298    /// internal bits differently, check the documentation of the intrinsic
    299    /// to see how it's being used.
    300    ///
    301    /// The in-memory representation of this type is the same as the one of an
    302    /// equivalent array (i.e. the in-memory order of elements is the same, and
    303    /// there is no padding); however, the alignment is different and equal to
    304    /// the size of the type. Note that the ABI for function calls may *not* be
    305    /// the same.
    306    ///
    307    /// Note that this means that an instance of `__m512i` typically just means
    308    /// a "bag of bits" which is left up to interpretation at the point of use.
    309    pub struct __m512i(8 x i64);
    310
    311    /// 512-bit wide set of sixteen `f32` types, x86-specific
    312    ///
    313    /// This type is the same as the `__m512` type defined by Intel,
    314    /// representing a 512-bit SIMD register which internally is consisted of
    315    /// eight packed `f32` instances. Usage of this type typically corresponds
    316    /// to the `avx512*` and up target features for x86/x86_64.
    317    ///
    318    /// Note that unlike `__m512i`, the integer version of the 512-bit
    319    /// registers, this `__m512` type has *one* interpretation. Each instance
    320    /// of `__m512` always corresponds to `f32x16`, or sixteen `f32` types
    321    /// packed together.
    322    ///
    323    /// The in-memory representation of this type is the same as the one of an
    324    /// equivalent array (i.e. the in-memory order of elements is the same, and
    325    /// there is no padding  between two consecutive elements); however, the
    326    /// alignment is different and equal to the size of the type. Note that the
    327    /// ABI for function calls may *not* be the same.
    328    ///
    329    /// Most intrinsics using `__m512` are prefixed with `_mm512_` and are
    330    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
    331    /// "pd" which is used for `__m512d`.
    332    pub struct __m512(16 x f32);
    333
    334    /// 512-bit wide set of eight `f64` types, x86-specific
    335    ///
    336    /// This type is the same as the `__m512d` type defined by Intel,
    337    /// representing a 512-bit SIMD register which internally is consisted of
    338    /// eight packed `f64` instances. Usage of this type typically corresponds
    339    /// to the `avx` and up target features for x86/x86_64.
    340    ///
    341    /// Note that unlike `__m512i`, the integer version of the 512-bit
    342    /// registers, this `__m512d` type has *one* interpretation. Each instance
    343    /// of `__m512d` always corresponds to `f64x8`, or eight `f64` types packed
    344    /// together.
    345    ///
    346    /// The in-memory representation of this type is the same as the one of an
    347    /// equivalent array (i.e. the in-memory order of elements is the same, and
    348    /// there is no padding  between two consecutive elements); however, the
    349    /// alignment is different and equal to the size of the type. Note that the
    350    /// ABI for function calls may *not* be the same.
    351    ///
    352    /// Most intrinsics using `__m512d` are prefixed with `_mm512_` and are
    353    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
    354    /// "ps" which is used for `__m512`.
    355    pub struct __m512d(8 x f64);
    356}
    357
    358types! {
    359    #![stable(feature = "stdarch_x86_avx512", since = "1.89")]
    360
    361    /// 128-bit wide set of eight `u16` types, x86-specific
    362    ///
    363    /// This type is representing a 128-bit SIMD register which internally is consisted of
    364    /// eight packed `u16` instances. Its purpose is for bf16 related intrinsic
    365    /// implementations.
    366    ///
    367    /// The in-memory representation of this type is the same as the one of an
    368    /// equivalent array (i.e. the in-memory order of elements is the same, and
    369    /// there is no padding); however, the alignment is different and equal to
    370    /// the size of the type. Note that the ABI for function calls may *not* be
    371    /// the same.
    372    pub struct __m128bh(8 x u16);
    373
    374    /// 256-bit wide set of 16 `u16` types, x86-specific
    375    ///
    376    /// This type is the same as the `__m256bh` type defined by Intel,
    377    /// representing a 256-bit SIMD register which internally is consisted of
    378    /// 16 packed `u16` instances. Its purpose is for bf16 related intrinsic
    379    /// implementations.
    380    ///
    381    /// The in-memory representation of this type is the same as the one of an
    382    /// equivalent array (i.e. the in-memory order of elements is the same, and
    383    /// there is no padding); however, the alignment is different and equal to
    384    /// the size of the type. Note that the ABI for function calls may *not* be
    385    /// the same.
    386    pub struct __m256bh(16 x u16);
    387
    388    /// 512-bit wide set of 32 `u16` types, x86-specific
    389    ///
    390    /// This type is the same as the `__m512bh` type defined by Intel,
    391    /// representing a 512-bit SIMD register which internally is consisted of
    392    /// 32 packed `u16` instances. Its purpose is for bf16 related intrinsic
    393    /// implementations.
    394    ///
    395    /// The in-memory representation of this type is the same as the one of an
    396    /// equivalent array (i.e. the in-memory order of elements is the same, and
    397    /// there is no padding); however, the alignment is different and equal to
    398    /// the size of the type. Note that the ABI for function calls may *not* be
    399    /// the same.
    400    pub struct __m512bh(32 x u16);
    401}
    402
    403types! {
    404    #![unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")]
    405
    406    /// 128-bit wide set of 8 `f16` types, x86-specific
    407    ///
    408    /// This type is the same as the `__m128h` type defined by Intel,
    409    /// representing a 128-bit SIMD register which internally is consisted of
    410    /// 8 packed `f16` instances. its purpose is for f16 related intrinsic
    411    /// implementations.
    412    ///
    413    /// The in-memory representation of this type is the same as the one of an
    414    /// equivalent array (i.e. the in-memory order of elements is the same, and
    415    /// there is no padding); however, the alignment is different and equal to
    416    /// the size of the type. Note that the ABI for function calls may *not* be
    417    /// the same.
    418    pub struct __m128h(8 x f16);
    419
    420    /// 256-bit wide set of 16 `f16` types, x86-specific
    421    ///
    422    /// This type is the same as the `__m256h` type defined by Intel,
    423    /// representing a 256-bit SIMD register which internally is consisted of
    424    /// 16 packed `f16` instances. its purpose is for f16 related intrinsic
    425    /// implementations.
    426    ///
    427    /// The in-memory representation of this type is the same as the one of an
    428    /// equivalent array (i.e. the in-memory order of elements is the same, and
    429    /// there is no padding); however, the alignment is different and equal to
    430    /// the size of the type. Note that the ABI for function calls may *not* be
    431    /// the same.
    432    pub struct __m256h(16 x f16);
    433
    434    /// 512-bit wide set of 32 `f16` types, x86-specific
    435    ///
    436    /// This type is the same as the `__m512h` type defined by Intel,
    437    /// representing a 512-bit SIMD register which internally is consisted of
    438    /// 32 packed `f16` instances. its purpose is for f16 related intrinsic
    439    /// implementations.
    440    ///
    441    /// The in-memory representation of this type is the same as the one of an
    442    /// equivalent array (i.e. the in-memory order of elements is the same, and
    443    /// there is no padding); however, the alignment is different and equal to
    444    /// the size of the type. Note that the ABI for function calls may *not* be
    445    /// the same.
    446    pub struct __m512h(32 x f16);
    447}
    448
    449/// The BFloat16 type used in AVX-512 intrinsics.
    450#[repr(transparent)]
    451#[derive(Copy, Clone, Debug)]
    452#[allow(non_camel_case_types)]
    453#[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
    454pub struct bf16(u16);
    455
    456impl bf16 {
    457    /// Raw transmutation from `u16`
    458    #[inline]
    459    #[must_use]
    460    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
    461    pub const fn from_bits(bits: u16) -> bf16 {
    462        bf16(bits)
    463    }
    464
    465    /// Raw transmutation to `u16`
    466    #[inline]
    467    #[must_use = "this returns the result of the operation, without modifying the original"]
    468    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
    469    pub const fn to_bits(self) -> u16 {
    470        self.0
    471    }
    472}
    473
    474/// The `__mmask64` type used in AVX-512 intrinsics, a 64-bit integer
    475#[allow(non_camel_case_types)]
    476#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    477pub type __mmask64 = u64;
    478
    479/// The `__mmask32` type used in AVX-512 intrinsics, a 32-bit integer
    480#[allow(non_camel_case_types)]
    481#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    482pub type __mmask32 = u32;
    483
    484/// The `__mmask16` type used in AVX-512 intrinsics, a 16-bit integer
    485#[allow(non_camel_case_types)]
    486#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    487pub type __mmask16 = u16;
    488
    489/// The `__mmask8` type used in AVX-512 intrinsics, a 8-bit integer
    490#[allow(non_camel_case_types)]
    491#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    492pub type __mmask8 = u8;
    493
    494/// The `_MM_CMPINT_ENUM` type used to specify comparison operations in AVX-512 intrinsics.
    495#[allow(non_camel_case_types)]
    496#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    497pub type _MM_CMPINT_ENUM = i32;
    498
    499/// The `MM_MANTISSA_NORM_ENUM` type used to specify mantissa normalized operations in AVX-512 intrinsics.
    500#[allow(non_camel_case_types)]
    501#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    502pub type _MM_MANTISSA_NORM_ENUM = i32;
    503
    504/// The `MM_MANTISSA_SIGN_ENUM` type used to specify mantissa signed operations in AVX-512 intrinsics.
    505#[allow(non_camel_case_types)]
    506#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    507pub type _MM_MANTISSA_SIGN_ENUM = i32;
    508
    509/// The `MM_PERM_ENUM` type used to specify shuffle operations in AVX-512 intrinsics.
    510#[allow(non_camel_case_types)]
    511#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    512pub type _MM_PERM_ENUM = i32;
    513
    514#[cfg(test)]
    515mod test;
    516#[cfg(test)]
    517pub use self::test::*;
    518
    519macro_rules! as_transmute {
    520    ($from:ty => $as_from:ident, $($as_to:ident -> $to:ident),* $(,)?) => {
    521        impl $from {$(
    522            #[inline]
    523            pub(crate) fn $as_to(self) -> crate::core_arch::simd::$to {
    524                unsafe { transmute(self) }
    525            }
    526        )*}
    527        $(
    528            impl crate::core_arch::simd::$to {
    529                #[inline]
    530                pub(crate) fn $as_from(self) -> $from {
    531                    unsafe { transmute(self) }
    532                }
    533            }
    534        )*
    535    };
    536}
    537
    538as_transmute!(__m128i =>
    539    as_m128i,
    540    as_u8x16 -> u8x16,
    541    as_u16x8 -> u16x8,
    542    as_u32x4 -> u32x4,
    543    as_u64x2 -> u64x2,
    544    as_i8x16 -> i8x16,
    545    as_i16x8 -> i16x8,
    546    as_i32x4 -> i32x4,
    547    as_i64x2 -> i64x2,
    548);
    549as_transmute!(__m256i =>
    550    as_m256i,
    551    as_u8x32 -> u8x32,
    552    as_u16x16 -> u16x16,
    553    as_u32x8 -> u32x8,
    554    as_u64x4 -> u64x4,
    555    as_i8x32 -> i8x32,
    556    as_i16x16 -> i16x16,
    557    as_i32x8 -> i32x8,
    558    as_i64x4 -> i64x4,
    559);
    560as_transmute!(__m512i =>
    561    as_m512i,
    562    as_u8x64 -> u8x64,
    563    as_u16x32 -> u16x32,
    564    as_u32x16 -> u32x16,
    565    as_u64x8 -> u64x8,
    566    as_i8x64 -> i8x64,
    567    as_i16x32 -> i16x32,
    568    as_i32x16 -> i32x16,
    569    as_i64x8 -> i64x8,
    570);
    571
    572as_transmute!(__m128 => as_m128, as_f32x4 -> f32x4);
    573as_transmute!(__m128d => as_m128d, as_f64x2 -> f64x2);
    574as_transmute!(__m256 => as_m256, as_f32x8 -> f32x8);
    575as_transmute!(__m256d => as_m256d, as_f64x4 -> f64x4);
    576as_transmute!(__m512 => as_m512, as_f32x16 -> f32x16);
    577as_transmute!(__m512d => as_m512d, as_f64x8 -> f64x8);
    578
    579as_transmute!(__m128bh =>
    580    as_m128bh,
    581    as_u16x8 -> u16x8,
    582    as_u32x4 -> u32x4,
    583    as_i16x8 -> i16x8,
    584    as_i32x4 -> i32x4,
    585);
    586as_transmute!(__m256bh =>
    587    as_m256bh,
    588    as_u16x16 -> u16x16,
    589    as_u32x8 -> u32x8,
    590    as_i16x16 -> i16x16,
    591    as_i32x8 -> i32x8,
    592);
    593as_transmute!(__m512bh =>
    594    as_m512bh,
    595    as_u16x32 -> u16x32,
    596    as_u32x16 -> u32x16,
    597    as_i16x32 -> i16x32,
    598    as_i32x16 -> i32x16,
    599);
    600
    601as_transmute!(__m128h => as_m128h, as_f16x8 -> f16x8);
    602as_transmute!(__m256h => as_m256h, as_f16x16 -> f16x16);
    603as_transmute!(__m512h => as_m512h, as_f16x32 -> f16x32);
    604
    605mod eflags;
    606#[stable(feature = "simd_x86", since = "1.27.0")]
    607pub use self::eflags::*;
    608
    609mod fxsr;
    610#[stable(feature = "simd_x86", since = "1.27.0")]
    611pub use self::fxsr::*;
    612
    613mod bswap;
    614#[stable(feature = "simd_x86", since = "1.27.0")]
    615pub use self::bswap::*;
    616
    617mod rdtsc;
    618#[stable(feature = "simd_x86", since = "1.27.0")]
    619pub use self::rdtsc::*;
    620
    621mod cpuid;
    622#[stable(feature = "simd_x86", since = "1.27.0")]
    623pub use self::cpuid::*;
    624mod xsave;
    625#[stable(feature = "simd_x86", since = "1.27.0")]
    626pub use self::xsave::*;
    627
    628mod sse;
    629#[stable(feature = "simd_x86", since = "1.27.0")]
    630pub use self::sse::*;
    631mod sse2;
    632#[stable(feature = "simd_x86", since = "1.27.0")]
    633pub use self::sse2::*;
    634mod sse3;
    635#[stable(feature = "simd_x86", since = "1.27.0")]
    636pub use self::sse3::*;
    637mod ssse3;
    638#[stable(feature = "simd_x86", since = "1.27.0")]
    639pub use self::ssse3::*;
    640mod sse41;
    641#[stable(feature = "simd_x86", since = "1.27.0")]
    642pub use self::sse41::*;
    643mod sse42;
    644#[stable(feature = "simd_x86", since = "1.27.0")]
    645pub use self::sse42::*;
    646mod avx;
    647#[stable(feature = "simd_x86", since = "1.27.0")]
    648pub use self::avx::*;
    649mod avx2;
    650#[stable(feature = "simd_x86", since = "1.27.0")]
    651pub use self::avx2::*;
    652mod fma;
    653#[stable(feature = "simd_x86", since = "1.27.0")]
    654pub use self::fma::*;
    655
    656mod abm;
    657#[stable(feature = "simd_x86", since = "1.27.0")]
    658pub use self::abm::*;
    659mod bmi1;
    660#[stable(feature = "simd_x86", since = "1.27.0")]
    661pub use self::bmi1::*;
    662
    663mod bmi2;
    664#[stable(feature = "simd_x86", since = "1.27.0")]
    665pub use self::bmi2::*;
    666
    667mod sse4a;
    668#[stable(feature = "simd_x86", since = "1.27.0")]
    669pub use self::sse4a::*;
    670
    671mod tbm;
    672#[stable(feature = "simd_x86", since = "1.27.0")]
    673pub use self::tbm::*;
    674
    675mod pclmulqdq;
    676#[stable(feature = "simd_x86", since = "1.27.0")]
    677pub use self::pclmulqdq::*;
    678
    679mod aes;
    680#[stable(feature = "simd_x86", since = "1.27.0")]
    681pub use self::aes::*;
    682
    683mod rdrand;
    684#[stable(feature = "simd_x86", since = "1.27.0")]
    685pub use self::rdrand::*;
    686
    687mod sha;
    688#[stable(feature = "simd_x86", since = "1.27.0")]
    689pub use self::sha::*;
    690
    691mod adx;
    692#[stable(feature = "simd_x86_adx", since = "1.33.0")]
    693pub use self::adx::*;
    694
    695#[cfg(test)]
    696use stdarch_test::assert_instr;
    697
    698mod avx512f;
    699#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    700pub use self::avx512f::*;
    701
    702mod avx512bw;
    703#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    704pub use self::avx512bw::*;
    705
    706mod avx512cd;
    707#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    708pub use self::avx512cd::*;
    709
    710mod avx512dq;
    711#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    712pub use self::avx512dq::*;
    713
    714mod avx512ifma;
    715#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    716pub use self::avx512ifma::*;
    717
    718mod avx512vbmi;
    719#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    720pub use self::avx512vbmi::*;
    721
    722mod avx512vbmi2;
    723#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    724pub use self::avx512vbmi2::*;
    725
    726mod avx512vnni;
    727#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    728pub use self::avx512vnni::*;
    729
    730mod avx512bitalg;
    731#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    732pub use self::avx512bitalg::*;
    733
    734mod gfni;
    735#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    736pub use self::gfni::*;
    737
    738mod avx512vpopcntdq;
    739#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    740pub use self::avx512vpopcntdq::*;
    741
    742mod vaes;
    743#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    744pub use self::vaes::*;
    745
    746mod vpclmulqdq;
    747#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    748pub use self::vpclmulqdq::*;
    749
    750mod bt;
    751#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
    752pub use self::bt::*;
    753
    754mod rtm;
    755#[unstable(feature = "stdarch_x86_rtm", issue = "111138")]
    756pub use self::rtm::*;
    757
    758mod f16c;
    759#[stable(feature = "x86_f16c_intrinsics", since = "1.68.0")]
    760pub use self::f16c::*;
    761
    762mod avx512bf16;
    763#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    764pub use self::avx512bf16::*;
    765
    766mod avxneconvert;
    767#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
    768pub use self::avxneconvert::*;
    769
    770mod avx512fp16;
    771#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")]
    772pub use self::avx512fp16::*;
    773
    774mod kl;
    775#[stable(feature = "keylocker_x86", since = "1.89.0")]
    776pub use self::kl::*;