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

#
core/stdarch/crates/core_arch/src/wasm32/
simd128.rs

    1//! This module implements the [WebAssembly `SIMD128` ISA].
    2//!
    3//! [WebAssembly `SIMD128` ISA]:
    4//! https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md
    5
    6#![allow(non_camel_case_types)]
    7#![allow(unused_imports)]
    8
    9use crate::{core_arch::simd, intrinsics::simd::*, marker::Sized, mem, ptr};
    10
    11#[cfg(test)]
    12use stdarch_test::assert_instr;
    13
    14types! {
    15    #![stable(feature = "wasm_simd", since = "1.54.0")]
    16
    17    /// WASM-specific 128-bit wide SIMD vector type.
    18    ///
    19    /// This type corresponds to the `v128` type in the [WebAssembly SIMD
    20    /// proposal](https://github.com/webassembly/simd). This type is 128-bits
    21    /// large and the meaning of all the bits is defined within the context of
    22    /// how this value is used.
    23    ///
    24    /// This same type is used simultaneously for all 128-bit-wide SIMD types,
    25    /// for example:
    26    ///
    27    /// * sixteen 8-bit integers (both `i8` and `u8`)
    28    /// * eight 16-bit integers (both `i16` and `u16`)
    29    /// * four 32-bit integers (both `i32` and `u32`)
    30    /// * two 64-bit integers (both `i64` and `u64`)
    31    /// * four 32-bit floats (`f32`)
    32    /// * two 64-bit floats (`f64`)
    33    ///
    34    /// The `v128` type in Rust is intended to be quite analogous to the `v128`
    35    /// type in WebAssembly. Operations on `v128` can only be performed with the
    36    /// functions in this module.
    37    // N.B., internals here are arbitrary.
    38    pub struct v128(4 x i32);
    39}
    40
    41macro_rules! conversions {
    42    ($(($name:ident = $ty:ty))*) => {
    43        impl v128 {
    44            $(
    45                #[inline(always)]
    46                pub(crate) fn $name(self) -> $ty {
    47                    unsafe { mem::transmute(self) }
    48                }
    49            )*
    50        }
    51        $(
    52            impl $ty {
    53                #[inline(always)]
    54                pub(crate) const fn v128(self) -> v128 {
    55                    unsafe { mem::transmute(self) }
    56                }
    57            }
    58        )*
    59    }
    60}
    61
    62conversions! {
    63    (as_u8x16 = simd::u8x16)
    64    (as_u16x8 = simd::u16x8)
    65    (as_u32x4 = simd::u32x4)
    66    (as_u64x2 = simd::u64x2)
    67    (as_i8x16 = simd::i8x16)
    68    (as_i16x8 = simd::i16x8)
    69    (as_i32x4 = simd::i32x4)
    70    (as_i64x2 = simd::i64x2)
    71    (as_f32x4 = simd::f32x4)
    72    (as_f64x2 = simd::f64x2)
    73}
    74
    75#[allow(improper_ctypes)]
    76unsafe extern "unadjusted" {
    77    #[link_name = "llvm.wasm.swizzle"]
    78    fn llvm_swizzle(a: simd::i8x16, b: simd::i8x16) -> simd::i8x16;
    79
    80    #[link_name = "llvm.wasm.bitselect.v16i8"]
    81    fn llvm_bitselect(a: simd::i8x16, b: simd::i8x16, c: simd::i8x16) -> simd::i8x16;
    82    #[link_name = "llvm.wasm.anytrue.v16i8"]
    83    fn llvm_any_true_i8x16(x: simd::i8x16) -> i32;
    84
    85    #[link_name = "llvm.wasm.alltrue.v16i8"]
    86    fn llvm_i8x16_all_true(x: simd::i8x16) -> i32;
    87    #[link_name = "llvm.wasm.bitmask.v16i8"]
    88    fn llvm_bitmask_i8x16(a: simd::i8x16) -> i32;
    89    #[link_name = "llvm.wasm.narrow.signed.v16i8.v8i16"]
    90    fn llvm_narrow_i8x16_s(a: simd::i16x8, b: simd::i16x8) -> simd::i8x16;
    91    #[link_name = "llvm.wasm.narrow.unsigned.v16i8.v8i16"]
    92    fn llvm_narrow_i8x16_u(a: simd::i16x8, b: simd::i16x8) -> simd::i8x16;
    93    #[link_name = "llvm.wasm.avgr.unsigned.v16i8"]
    94    fn llvm_avgr_u_i8x16(a: simd::i8x16, b: simd::i8x16) -> simd::i8x16;
    95
    96    #[link_name = "llvm.wasm.extadd.pairwise.signed.v8i16"]
    97    fn llvm_i16x8_extadd_pairwise_i8x16_s(x: simd::i8x16) -> simd::i16x8;
    98    #[link_name = "llvm.wasm.extadd.pairwise.unsigned.v8i16"]
    99    fn llvm_i16x8_extadd_pairwise_i8x16_u(x: simd::i8x16) -> simd::i16x8;
    100    #[link_name = "llvm.wasm.q15mulr.sat.signed"]
    101    fn llvm_q15mulr(a: simd::i16x8, b: simd::i16x8) -> simd::i16x8;
    102    #[link_name = "llvm.wasm.alltrue.v8i16"]
    103    fn llvm_i16x8_all_true(x: simd::i16x8) -> i32;
    104    #[link_name = "llvm.wasm.bitmask.v8i16"]
    105    fn llvm_bitmask_i16x8(a: simd::i16x8) -> i32;
    106    #[link_name = "llvm.wasm.narrow.signed.v8i16.v4i32"]
    107    fn llvm_narrow_i16x8_s(a: simd::i32x4, b: simd::i32x4) -> simd::i16x8;
    108    #[link_name = "llvm.wasm.narrow.unsigned.v8i16.v4i32"]
    109    fn llvm_narrow_i16x8_u(a: simd::i32x4, b: simd::i32x4) -> simd::i16x8;
    110    #[link_name = "llvm.wasm.avgr.unsigned.v8i16"]
    111    fn llvm_avgr_u_i16x8(a: simd::i16x8, b: simd::i16x8) -> simd::i16x8;
    112
    113    #[link_name = "llvm.wasm.extadd.pairwise.signed.v4i32"]
    114    fn llvm_i32x4_extadd_pairwise_i16x8_s(x: simd::i16x8) -> simd::i32x4;
    115    #[link_name = "llvm.wasm.extadd.pairwise.unsigned.v4i32"]
    116    fn llvm_i32x4_extadd_pairwise_i16x8_u(x: simd::i16x8) -> simd::i32x4;
    117    #[link_name = "llvm.wasm.alltrue.v4i32"]
    118    fn llvm_i32x4_all_true(x: simd::i32x4) -> i32;
    119    #[link_name = "llvm.wasm.bitmask.v4i32"]
    120    fn llvm_bitmask_i32x4(a: simd::i32x4) -> i32;
    121    #[link_name = "llvm.wasm.dot"]
    122    fn llvm_i32x4_dot_i16x8_s(a: simd::i16x8, b: simd::i16x8) -> simd::i32x4;
    123
    124    #[link_name = "llvm.wasm.alltrue.v2i64"]
    125    fn llvm_i64x2_all_true(x: simd::i64x2) -> i32;
    126    #[link_name = "llvm.wasm.bitmask.v2i64"]
    127    fn llvm_bitmask_i64x2(a: simd::i64x2) -> i32;
    128
    129    #[link_name = "llvm.nearbyint.v4f32"]
    130    fn llvm_f32x4_nearest(x: simd::f32x4) -> simd::f32x4;
    131    #[link_name = "llvm.minimum.v4f32"]
    132    fn llvm_f32x4_min(x: simd::f32x4, y: simd::f32x4) -> simd::f32x4;
    133    #[link_name = "llvm.maximum.v4f32"]
    134    fn llvm_f32x4_max(x: simd::f32x4, y: simd::f32x4) -> simd::f32x4;
    135
    136    #[link_name = "llvm.nearbyint.v2f64"]
    137    fn llvm_f64x2_nearest(x: simd::f64x2) -> simd::f64x2;
    138    #[link_name = "llvm.minimum.v2f64"]
    139    fn llvm_f64x2_min(x: simd::f64x2, y: simd::f64x2) -> simd::f64x2;
    140    #[link_name = "llvm.maximum.v2f64"]
    141    fn llvm_f64x2_max(x: simd::f64x2, y: simd::f64x2) -> simd::f64x2;
    142}
    143
    144/// Loads a `v128` vector from the given heap address.
    145///
    146/// This intrinsic will emit a load with an alignment of 1. While this is
    147/// provided for completeness it is not strictly necessary, you can also load
    148/// the pointer directly:
    149///
    150/// ```rust,ignore
    151/// let a: &v128 = ...;
    152/// let value = unsafe { v128_load(a) };
    153/// // .. is the same as ..
    154/// let value = *a;
    155/// ```
    156///
    157/// The alignment of the load can be configured by doing a manual load without
    158/// this intrinsic.
    159///
    160/// # Unsafety
    161///
    162/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    163/// the pointer must be valid to load 16 bytes from. Note that there is no
    164/// alignment requirement on this pointer since this intrinsic performs a
    165/// 1-aligned load.
    166#[inline]
    167#[cfg_attr(test, assert_instr(v128.load))]
    168#[target_feature(enable = "simd128")]
    169#[doc(alias("v128.load"))]
    170#[stable(feature = "wasm_simd", since = "1.54.0")]
    171pub unsafe fn v128_load(m: *const v128) -> v128 {
    172    m.read_unaligned()
    173}
    174
    175/// Load eight 8-bit integers and sign extend each one to a 16-bit lane
    176///
    177/// # Unsafety
    178///
    179/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    180/// the pointer must be valid to load 8 bytes from. Note that there is no
    181/// alignment requirement on this pointer since this intrinsic performs a
    182/// 1-aligned load.
    183#[inline]
    184#[cfg_attr(test, assert_instr(v128.load8x8_s))]
    185#[target_feature(enable = "simd128")]
    186#[doc(alias("v128.load8x8_s"))]
    187#[stable(feature = "wasm_simd", since = "1.54.0")]
    188pub unsafe fn i16x8_load_extend_i8x8(m: *const i8) -> v128 {
    189    let m = m.cast::<simd::i8x8>().read_unaligned();
    190    simd_cast::<_, simd::i16x8>(m).v128()
    191}
    192
    193/// Load eight 8-bit integers and zero extend each one to a 16-bit lane
    194///
    195/// # Unsafety
    196///
    197/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    198/// the pointer must be valid to load 8 bytes from. Note that there is no
    199/// alignment requirement on this pointer since this intrinsic performs a
    200/// 1-aligned load.
    201#[inline]
    202#[cfg_attr(test, assert_instr(v128.load8x8_u))]
    203#[target_feature(enable = "simd128")]
    204#[doc(alias("v128.load8x8_u"))]
    205#[stable(feature = "wasm_simd", since = "1.54.0")]
    206pub unsafe fn i16x8_load_extend_u8x8(m: *const u8) -> v128 {
    207    let m = m.cast::<simd::u8x8>().read_unaligned();
    208    simd_cast::<_, simd::u16x8>(m).v128()
    209}
    210
    211#[stable(feature = "wasm_simd", since = "1.54.0")]
    212pub use i16x8_load_extend_u8x8 as u16x8_load_extend_u8x8;
    213
    214/// Load four 16-bit integers and sign extend each one to a 32-bit lane
    215///
    216/// # Unsafety
    217///
    218/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    219/// the pointer must be valid to load 8 bytes from. Note that there is no
    220/// alignment requirement on this pointer since this intrinsic performs a
    221/// 1-aligned load.
    222#[inline]
    223#[cfg_attr(test, assert_instr(v128.load16x4_s))]
    224#[target_feature(enable = "simd128")]
    225#[doc(alias("v128.load16x4_s"))]
    226#[stable(feature = "wasm_simd", since = "1.54.0")]
    227pub unsafe fn i32x4_load_extend_i16x4(m: *const i16) -> v128 {
    228    let m = m.cast::<simd::i16x4>().read_unaligned();
    229    simd_cast::<_, simd::i32x4>(m).v128()
    230}
    231
    232/// Load four 16-bit integers and zero extend each one to a 32-bit lane
    233///
    234/// # Unsafety
    235///
    236/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    237/// the pointer must be valid to load 8 bytes from. Note that there is no
    238/// alignment requirement on this pointer since this intrinsic performs a
    239/// 1-aligned load.
    240#[inline]
    241#[cfg_attr(test, assert_instr(v128.load16x4_u))]
    242#[target_feature(enable = "simd128")]
    243#[doc(alias("v128.load16x4_u"))]
    244#[stable(feature = "wasm_simd", since = "1.54.0")]
    245pub unsafe fn i32x4_load_extend_u16x4(m: *const u16) -> v128 {
    246    let m = m.cast::<simd::u16x4>().read_unaligned();
    247    simd_cast::<_, simd::u32x4>(m).v128()
    248}
    249
    250#[stable(feature = "wasm_simd", since = "1.54.0")]
    251pub use i32x4_load_extend_u16x4 as u32x4_load_extend_u16x4;
    252
    253/// Load two 32-bit integers and sign extend each one to a 64-bit lane
    254///
    255/// # Unsafety
    256///
    257/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    258/// the pointer must be valid to load 8 bytes from. Note that there is no
    259/// alignment requirement on this pointer since this intrinsic performs a
    260/// 1-aligned load.
    261#[inline]
    262#[cfg_attr(test, assert_instr(v128.load32x2_s))]
    263#[target_feature(enable = "simd128")]
    264#[doc(alias("v128.load32x2_s"))]
    265#[stable(feature = "wasm_simd", since = "1.54.0")]
    266pub unsafe fn i64x2_load_extend_i32x2(m: *const i32) -> v128 {
    267    let m = m.cast::<simd::i32x2>().read_unaligned();
    268    simd_cast::<_, simd::i64x2>(m).v128()
    269}
    270
    271/// Load two 32-bit integers and zero extend each one to a 64-bit lane
    272///
    273/// # Unsafety
    274///
    275/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    276/// the pointer must be valid to load 8 bytes from. Note that there is no
    277/// alignment requirement on this pointer since this intrinsic performs a
    278/// 1-aligned load.
    279#[inline]
    280#[cfg_attr(test, assert_instr(v128.load32x2_u))]
    281#[target_feature(enable = "simd128")]
    282#[doc(alias("v128.load32x2_u"))]
    283#[stable(feature = "wasm_simd", since = "1.54.0")]
    284pub unsafe fn i64x2_load_extend_u32x2(m: *const u32) -> v128 {
    285    let m = m.cast::<simd::u32x2>().read_unaligned();
    286    simd_cast::<_, simd::u64x2>(m).v128()
    287}
    288
    289#[stable(feature = "wasm_simd", since = "1.54.0")]
    290pub use i64x2_load_extend_u32x2 as u64x2_load_extend_u32x2;
    291
    292/// Load a single element and splat to all lanes of a v128 vector.
    293///
    294/// While this intrinsic is provided for completeness it can also be replaced
    295/// with `u8x16_splat(*m)` and it should generate equivalent code (and also not
    296/// require `unsafe`).
    297///
    298/// # Unsafety
    299///
    300/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    301/// the pointer must be valid to load 1 byte from. Note that there is no
    302/// alignment requirement on this pointer since this intrinsic performs a
    303/// 1-aligned load.
    304#[inline]
    305#[cfg_attr(test, assert_instr(v128.load8_splat))]
    306#[target_feature(enable = "simd128")]
    307#[doc(alias("v128.load8_splat"))]
    308#[stable(feature = "wasm_simd", since = "1.54.0")]
    309pub unsafe fn v128_load8_splat(m: *const u8) -> v128 {
    310    u8x16_splat(*m)
    311}
    312
    313/// Load a single element and splat to all lanes of a v128 vector.
    314///
    315/// While this intrinsic is provided for completeness it can also be replaced
    316/// with `u16x8_splat(*m)` and it should generate equivalent code (and also not
    317/// require `unsafe`).
    318///
    319/// # Unsafety
    320///
    321/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    322/// the pointer must be valid to load 2 bytes from. Note that there is no
    323/// alignment requirement on this pointer since this intrinsic performs a
    324/// 1-aligned load.
    325#[inline]
    326#[cfg_attr(test, assert_instr(v128.load16_splat))]
    327#[target_feature(enable = "simd128")]
    328#[doc(alias("v128.load16_splat"))]
    329#[stable(feature = "wasm_simd", since = "1.54.0")]
    330pub unsafe fn v128_load16_splat(m: *const u16) -> v128 {
    331    u16x8_splat(ptr::read_unaligned(m))
    332}
    333
    334/// Load a single element and splat to all lanes of a v128 vector.
    335///
    336/// While this intrinsic is provided for completeness it can also be replaced
    337/// with `u32x4_splat(*m)` and it should generate equivalent code (and also not
    338/// require `unsafe`).
    339///
    340/// # Unsafety
    341///
    342/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    343/// the pointer must be valid to load 4 bytes from. Note that there is no
    344/// alignment requirement on this pointer since this intrinsic performs a
    345/// 1-aligned load.
    346#[inline]
    347#[cfg_attr(test, assert_instr(v128.load32_splat))]
    348#[target_feature(enable = "simd128")]
    349#[doc(alias("v128.load32_splat"))]
    350#[stable(feature = "wasm_simd", since = "1.54.0")]
    351pub unsafe fn v128_load32_splat(m: *const u32) -> v128 {
    352    u32x4_splat(ptr::read_unaligned(m))
    353}
    354
    355/// Load a single element and splat to all lanes of a v128 vector.
    356///
    357/// While this intrinsic is provided for completeness it can also be replaced
    358/// with `u64x2_splat(*m)` and it should generate equivalent code (and also not
    359/// require `unsafe`).
    360///
    361/// # Unsafety
    362///
    363/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    364/// the pointer must be valid to load 8 bytes from. Note that there is no
    365/// alignment requirement on this pointer since this intrinsic performs a
    366/// 1-aligned load.
    367#[inline]
    368#[cfg_attr(test, assert_instr(v128.load64_splat))]
    369#[target_feature(enable = "simd128")]
    370#[doc(alias("v128.load64_splat"))]
    371#[stable(feature = "wasm_simd", since = "1.54.0")]
    372pub unsafe fn v128_load64_splat(m: *const u64) -> v128 {
    373    u64x2_splat(ptr::read_unaligned(m))
    374}
    375
    376/// Load a 32-bit element into the low bits of the vector and sets all other
    377/// bits to zero.
    378///
    379/// This intrinsic is provided for completeness and is equivalent to `u32x4(*m,
    380/// 0, 0, 0)` (which doesn't require `unsafe`).
    381///
    382/// # Unsafety
    383///
    384/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    385/// the pointer must be valid to load 4 bytes from. Note that there is no
    386/// alignment requirement on this pointer since this intrinsic performs a
    387/// 1-aligned load.
    388#[inline]
    389#[cfg_attr(test, assert_instr(v128.load32_zero))]
    390#[target_feature(enable = "simd128")]
    391#[doc(alias("v128.load32_zero"))]
    392#[stable(feature = "wasm_simd", since = "1.54.0")]
    393pub unsafe fn v128_load32_zero(m: *const u32) -> v128 {
    394    u32x4(ptr::read_unaligned(m), 0, 0, 0)
    395}
    396
    397/// Load a 64-bit element into the low bits of the vector and sets all other
    398/// bits to zero.
    399///
    400/// This intrinsic is provided for completeness and is equivalent to
    401/// `u64x2_replace_lane::<0>(u64x2(0, 0), *m)` (which doesn't require `unsafe`).
    402///
    403/// # Unsafety
    404///
    405/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    406/// the pointer must be valid to load 8 bytes from. Note that there is no
    407/// alignment requirement on this pointer since this intrinsic performs a
    408/// 1-aligned load.
    409#[inline]
    410#[cfg_attr(test, assert_instr(v128.load64_zero))]
    411#[target_feature(enable = "simd128")]
    412#[doc(alias("v128.load64_zero"))]
    413#[stable(feature = "wasm_simd", since = "1.54.0")]
    414pub unsafe fn v128_load64_zero(m: *const u64) -> v128 {
    415    u64x2_replace_lane::<0>(u64x2(0, 0), ptr::read_unaligned(m))
    416}
    417
    418/// Stores a `v128` vector to the given heap address.
    419///
    420/// This intrinsic will emit a store with an alignment of 1. While this is
    421/// provided for completeness it is not strictly necessary, you can also store
    422/// the pointer directly:
    423///
    424/// ```rust,ignore
    425/// let a: &mut v128 = ...;
    426/// unsafe { v128_store(a, value) };
    427/// // .. is the same as ..
    428/// *a = value;
    429/// ```
    430///
    431/// The alignment of the store can be configured by doing a manual store without
    432/// this intrinsic.
    433///
    434/// # Unsafety
    435///
    436/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    437/// the pointer must be valid to store 16 bytes to. Note that there is no
    438/// alignment requirement on this pointer since this intrinsic performs a
    439/// 1-aligned store.
    440#[inline]
    441#[cfg_attr(test, assert_instr(v128.store))]
    442#[target_feature(enable = "simd128")]
    443#[doc(alias("v128.store"))]
    444#[stable(feature = "wasm_simd", since = "1.54.0")]
    445pub unsafe fn v128_store(m: *mut v128, a: v128) {
    446    m.write_unaligned(a)
    447}
    448
    449/// Loads an 8-bit value from `m` and sets lane `L` of `v` to that value.
    450///
    451/// This intrinsic is provided for completeness and is equivalent to
    452/// `u8x16_replace_lane::<L>(v, *m)` (which doesn't require `unsafe`).
    453///
    454/// # Unsafety
    455///
    456/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    457/// the pointer must be valid to load 1 byte from. Note that there is no
    458/// alignment requirement on this pointer since this intrinsic performs a
    459/// 1-aligned load.
    460#[inline]
    461#[cfg_attr(test, assert_instr(v128.load8_lane, L = 0))]
    462#[target_feature(enable = "simd128")]
    463#[doc(alias("v128.load8_lane"))]
    464#[stable(feature = "wasm_simd", since = "1.54.0")]
    465pub unsafe fn v128_load8_lane<const L: usize>(v: v128, m: *const u8) -> v128 {
    466    u8x16_replace_lane::<L>(v, *m)
    467}
    468
    469/// Loads a 16-bit value from `m` and sets lane `L` of `v` to that value.
    470///
    471/// This intrinsic is provided for completeness and is equivalent to
    472/// `u16x8_replace_lane::<L>(v, *m)` (which doesn't require `unsafe`).
    473///
    474/// # Unsafety
    475///
    476/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    477/// the pointer must be valid to load 2 bytes from. Note that there is no
    478/// alignment requirement on this pointer since this intrinsic performs a
    479/// 1-aligned load.
    480#[inline]
    481#[cfg_attr(test, assert_instr(v128.load16_lane, L = 0))]
    482#[target_feature(enable = "simd128")]
    483#[doc(alias("v128.load16_lane"))]
    484#[stable(feature = "wasm_simd", since = "1.54.0")]
    485pub unsafe fn v128_load16_lane<const L: usize>(v: v128, m: *const u16) -> v128 {
    486    u16x8_replace_lane::<L>(v, ptr::read_unaligned(m))
    487}
    488
    489/// Loads a 32-bit value from `m` and sets lane `L` of `v` to that value.
    490///
    491/// This intrinsic is provided for completeness and is equivalent to
    492/// `u32x4_replace_lane::<L>(v, *m)` (which doesn't require `unsafe`).
    493///
    494/// # Unsafety
    495///
    496/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    497/// the pointer must be valid to load 4 bytes from. Note that there is no
    498/// alignment requirement on this pointer since this intrinsic performs a
    499/// 1-aligned load.
    500#[inline]
    501#[cfg_attr(test, assert_instr(v128.load32_lane, L = 0))]
    502#[target_feature(enable = "simd128")]
    503#[doc(alias("v128.load32_lane"))]
    504#[stable(feature = "wasm_simd", since = "1.54.0")]
    505pub unsafe fn v128_load32_lane<const L: usize>(v: v128, m: *const u32) -> v128 {
    506    u32x4_replace_lane::<L>(v, ptr::read_unaligned(m))
    507}
    508
    509/// Loads a 64-bit value from `m` and sets lane `L` of `v` to that value.
    510///
    511/// This intrinsic is provided for completeness and is equivalent to
    512/// `u64x2_replace_lane::<L>(v, *m)` (which doesn't require `unsafe`).
    513///
    514/// # Unsafety
    515///
    516/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    517/// the pointer must be valid to load 8 bytes from. Note that there is no
    518/// alignment requirement on this pointer since this intrinsic performs a
    519/// 1-aligned load.
    520#[inline]
    521#[cfg_attr(test, assert_instr(v128.load64_lane, L = 0))]
    522#[target_feature(enable = "simd128")]
    523#[doc(alias("v128.load64_lane"))]
    524#[stable(feature = "wasm_simd", since = "1.54.0")]
    525pub unsafe fn v128_load64_lane<const L: usize>(v: v128, m: *const u64) -> v128 {
    526    u64x2_replace_lane::<L>(v, ptr::read_unaligned(m))
    527}
    528
    529/// Stores the 8-bit value from lane `L` of `v` into `m`
    530///
    531/// This intrinsic is provided for completeness and is equivalent to
    532/// `*m = u8x16_extract_lane::<L>(v)` (which doesn't require `unsafe`).
    533///
    534/// # Unsafety
    535///
    536/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    537/// the pointer must be valid to store 1 byte to. Note that there is no
    538/// alignment requirement on this pointer since this intrinsic performs a
    539/// 1-aligned store.
    540#[inline]
    541#[cfg_attr(test, assert_instr(v128.store8_lane, L = 0))]
    542#[target_feature(enable = "simd128")]
    543#[doc(alias("v128.store8_lane"))]
    544#[stable(feature = "wasm_simd", since = "1.54.0")]
    545pub unsafe fn v128_store8_lane<const L: usize>(v: v128, m: *mut u8) {
    546    *m = u8x16_extract_lane::<L>(v);
    547}
    548
    549/// Stores the 16-bit value from lane `L` of `v` into `m`
    550///
    551/// This intrinsic is provided for completeness and is equivalent to
    552/// `*m = u16x8_extract_lane::<L>(v)` (which doesn't require `unsafe`).
    553///
    554/// # Unsafety
    555///
    556/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    557/// the pointer must be valid to store 2 bytes to. Note that there is no
    558/// alignment requirement on this pointer since this intrinsic performs a
    559/// 1-aligned store.
    560#[inline]
    561#[cfg_attr(test, assert_instr(v128.store16_lane, L = 0))]
    562#[target_feature(enable = "simd128")]
    563#[doc(alias("v128.store16_lane"))]
    564#[stable(feature = "wasm_simd", since = "1.54.0")]
    565pub unsafe fn v128_store16_lane<const L: usize>(v: v128, m: *mut u16) {
    566    ptr::write_unaligned(m, u16x8_extract_lane::<L>(v))
    567}
    568
    569/// Stores the 32-bit value from lane `L` of `v` into `m`
    570///
    571/// This intrinsic is provided for completeness and is equivalent to
    572/// `*m = u32x4_extract_lane::<L>(v)` (which doesn't require `unsafe`).
    573///
    574/// # Unsafety
    575///
    576/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    577/// the pointer must be valid to store 4 bytes to. Note that there is no
    578/// alignment requirement on this pointer since this intrinsic performs a
    579/// 1-aligned store.
    580#[inline]
    581#[cfg_attr(test, assert_instr(v128.store32_lane, L = 0))]
    582#[target_feature(enable = "simd128")]
    583#[doc(alias("v128.store32_lane"))]
    584#[stable(feature = "wasm_simd", since = "1.54.0")]
    585pub unsafe fn v128_store32_lane<const L: usize>(v: v128, m: *mut u32) {
    586    ptr::write_unaligned(m, u32x4_extract_lane::<L>(v))
    587}
    588
    589/// Stores the 64-bit value from lane `L` of `v` into `m`
    590///
    591/// This intrinsic is provided for completeness and is equivalent to
    592/// `*m = u64x2_extract_lane::<L>(v)` (which doesn't require `unsafe`).
    593///
    594/// # Unsafety
    595///
    596/// This intrinsic is unsafe because it takes a raw pointer as an argument, and
    597/// the pointer must be valid to store 8 bytes to. Note that there is no
    598/// alignment requirement on this pointer since this intrinsic performs a
    599/// 1-aligned store.
    600#[inline]
    601#[cfg_attr(test, assert_instr(v128.store64_lane, L = 0))]
    602#[target_feature(enable = "simd128")]
    603#[doc(alias("v128.store64_lane"))]
    604#[stable(feature = "wasm_simd", since = "1.54.0")]
    605pub unsafe fn v128_store64_lane<const L: usize>(v: v128, m: *mut u64) {
    606    ptr::write_unaligned(m, u64x2_extract_lane::<L>(v))
    607}
    608
    609/// Materializes a SIMD value from the provided operands.
    610///
    611/// If possible this will generate a `v128.const` instruction, otherwise it may
    612/// be lowered to a sequence of instructions to materialize the vector value.
    613#[inline]
    614#[cfg_attr(
    615    test,
    616    assert_instr(
    617        v128.const,
    618        a0 = 0,
    619        a1 = 1,
    620        a2 = 2,
    621        a3 = 3,
    622        a4 = 4,
    623        a5 = 5,
    624        a6 = 6,
    625        a7 = 7,
    626        a8 = 8,
    627        a9 = 9,
    628        a10 = 10,
    629        a11 = 11,
    630        a12 = 12,
    631        a13 = 13,
    632        a14 = 14,
    633        a15 = 15,
    634    )
    635)]
    636#[doc(alias("v128.const"))]
    637#[stable(feature = "wasm_simd", since = "1.54.0")]
    638#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    639#[target_feature(enable = "simd128")]
    640pub const fn i8x16(
    641    a0: i8,
    642    a1: i8,
    643    a2: i8,
    644    a3: i8,
    645    a4: i8,
    646    a5: i8,
    647    a6: i8,
    648    a7: i8,
    649    a8: i8,
    650    a9: i8,
    651    a10: i8,
    652    a11: i8,
    653    a12: i8,
    654    a13: i8,
    655    a14: i8,
    656    a15: i8,
    657) -> v128 {
    658    simd::i8x16::new(
    659        a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
    660    )
    661    .v128()
    662}
    663
    664/// Materializes a SIMD value from the provided operands.
    665///
    666/// If possible this will generate a `v128.const` instruction, otherwise it may
    667/// be lowered to a sequence of instructions to materialize the vector value.
    668#[inline]
    669#[doc(alias("v128.const"))]
    670#[stable(feature = "wasm_simd", since = "1.54.0")]
    671#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    672#[target_feature(enable = "simd128")]
    673pub const fn u8x16(
    674    a0: u8,
    675    a1: u8,
    676    a2: u8,
    677    a3: u8,
    678    a4: u8,
    679    a5: u8,
    680    a6: u8,
    681    a7: u8,
    682    a8: u8,
    683    a9: u8,
    684    a10: u8,
    685    a11: u8,
    686    a12: u8,
    687    a13: u8,
    688    a14: u8,
    689    a15: u8,
    690) -> v128 {
    691    simd::u8x16::new(
    692        a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
    693    )
    694    .v128()
    695}
    696
    697/// Materializes a SIMD value from the provided operands.
    698///
    699/// If possible this will generate a `v128.const` instruction, otherwise it may
    700/// be lowered to a sequence of instructions to materialize the vector value.
    701#[inline]
    702#[cfg_attr(
    703    test,
    704    assert_instr(
    705        v128.const,
    706        a0 = 0,
    707        a1 = 1,
    708        a2 = 2,
    709        a3 = 3,
    710        a4 = 4,
    711        a5 = 5,
    712        a6 = 6,
    713        a7 = 7,
    714    )
    715)]
    716#[doc(alias("v128.const"))]
    717#[stable(feature = "wasm_simd", since = "1.54.0")]
    718#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    719#[target_feature(enable = "simd128")]
    720pub const fn i16x8(a0: i16, a1: i16, a2: i16, a3: i16, a4: i16, a5: i16, a6: i16, a7: i16) -> v128 {
    721    simd::i16x8::new(a0, a1, a2, a3, a4, a5, a6, a7).v128()
    722}
    723
    724/// Materializes a SIMD value from the provided operands.
    725///
    726/// If possible this will generate a `v128.const` instruction, otherwise it may
    727/// be lowered to a sequence of instructions to materialize the vector value.
    728#[inline]
    729#[doc(alias("v128.const"))]
    730#[stable(feature = "wasm_simd", since = "1.54.0")]
    731#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    732#[target_feature(enable = "simd128")]
    733pub const fn u16x8(a0: u16, a1: u16, a2: u16, a3: u16, a4: u16, a5: u16, a6: u16, a7: u16) -> v128 {
    734    simd::u16x8::new(a0, a1, a2, a3, a4, a5, a6, a7).v128()
    735}
    736
    737/// Materializes a SIMD value from the provided operands.
    738///
    739/// If possible this will generate a `v128.const` instruction, otherwise it may
    740/// be lowered to a sequence of instructions to materialize the vector value.
    741#[inline]
    742#[cfg_attr(test, assert_instr(v128.const, a0 = 0, a1 = 1, a2 = 2, a3 = 3))]
    743#[doc(alias("v128.const"))]
    744#[stable(feature = "wasm_simd", since = "1.54.0")]
    745#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    746#[target_feature(enable = "simd128")]
    747pub const fn i32x4(a0: i32, a1: i32, a2: i32, a3: i32) -> v128 {
    748    simd::i32x4::new(a0, a1, a2, a3).v128()
    749}
    750
    751/// Materializes a SIMD value from the provided operands.
    752///
    753/// If possible this will generate a `v128.const` instruction, otherwise it may
    754/// be lowered to a sequence of instructions to materialize the vector value.
    755#[inline]
    756#[doc(alias("v128.const"))]
    757#[stable(feature = "wasm_simd", since = "1.54.0")]
    758#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    759#[target_feature(enable = "simd128")]
    760pub const fn u32x4(a0: u32, a1: u32, a2: u32, a3: u32) -> v128 {
    761    simd::u32x4::new(a0, a1, a2, a3).v128()
    762}
    763
    764/// Materializes a SIMD value from the provided operands.
    765///
    766/// If possible this will generate a `v128.const` instruction, otherwise it may
    767/// be lowered to a sequence of instructions to materialize the vector value.
    768#[inline]
    769#[cfg_attr(test, assert_instr(v128.const, a0 = 1, a1 = 2))]
    770#[doc(alias("v128.const"))]
    771#[stable(feature = "wasm_simd", since = "1.54.0")]
    772#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    773#[target_feature(enable = "simd128")]
    774pub const fn i64x2(a0: i64, a1: i64) -> v128 {
    775    simd::i64x2::new(a0, a1).v128()
    776}
    777
    778/// Materializes a SIMD value from the provided operands.
    779///
    780/// If possible this will generate a `v128.const` instruction, otherwise it may
    781/// be lowered to a sequence of instructions to materialize the vector value.
    782#[inline]
    783#[doc(alias("v128.const"))]
    784#[stable(feature = "wasm_simd", since = "1.54.0")]
    785#[rustc_const_stable(feature = "wasm_simd", since = "1.54.0")]
    786#[target_feature(enable = "simd128")]
    787pub const fn u64x2(a0: u64, a1: u64) -> v128 {
    788    simd::u64x2::new(a0, a1).v128()
    789}
    790
    791/// Materializes a SIMD value from the provided operands.
    792///
    793/// If possible this will generate a `v128.const` instruction, otherwise it may
    794/// be lowered to a sequence of instructions to materialize the vector value.
    795#[inline]
    796#[cfg_attr(test, assert_instr(v128.const, a0 = 0.0, a1 = 1.0, a2 = 2.0, a3 = 3.0))]
    797#[doc(alias("v128.const"))]
    798#[stable(feature = "wasm_simd", since = "1.54.0")]
    799#[rustc_const_stable(feature = "wasm_simd_const", since = "1.56.0")]
    800#[target_feature(enable = "simd128")]
    801pub const fn f32x4(a0: f32, a1: f32, a2: f32, a3: f32) -> v128 {
    802    simd::f32x4::new(a0, a1, a2, a3).v128()
    803}
    804
    805/// Materializes a SIMD value from the provided operands.
    806///
    807/// If possible this will generate a `v128.const` instruction, otherwise it may
    808/// be lowered to a sequence of instructions to materialize the vector value.
    809#[inline]
    810#[cfg_attr(test, assert_instr(v128.const, a0 = 0.0, a1 = 1.0))]
    811#[doc(alias("v128.const"))]
    812#[stable(feature = "wasm_simd", since = "1.54.0")]
    813#[rustc_const_stable(feature = "wasm_simd_const", since = "1.56.0")]
    814#[target_feature(enable = "simd128")]
    815pub const fn f64x2(a0: f64, a1: f64) -> v128 {
    816    simd::f64x2::new(a0, a1).v128()
    817}
    818
    819/// Returns a new vector with lanes selected from the lanes of the two input
    820/// vectors `$a` and `$b` specified in the 16 immediate operands.
    821///
    822/// The `$a` and `$b` expressions must have type `v128`, and this function
    823/// generates a wasm instruction that is encoded with 16 bytes providing the
    824/// indices of the elements to return. The indices `i` in range [0, 15] select
    825/// the `i`-th element of `a`. The indices in range [16, 31] select the `i -
    826/// 16`-th element of `b`.
    827///
    828/// Note that this is a macro due to the codegen requirements of all of the
    829/// index expressions `$i*` must be constant. A compiler error will be
    830/// generated if any of the expressions are not constant.
    831///
    832/// All indexes `$i*` must have the type `u32`.
    833#[inline]
    834#[cfg_attr(test,
    835    assert_instr(
    836        i8x16.shuffle,
    837        I0 = 0,
    838        I1 = 2,
    839        I2 = 4,
    840        I3 = 6,
    841        I4 = 8,
    842        I5 = 10,
    843        I6 = 12,
    844        I7 = 14,
    845        I8 = 16,
    846        I9 = 18,
    847        I10 = 20,
    848        I11 = 22,
    849        I12 = 24,
    850        I13 = 26,
    851        I14 = 28,
    852        I15 = 30,
    853    )
    854)]
    855#[target_feature(enable = "simd128")]
    856#[doc(alias("i8x16.shuffle"))]
    857#[stable(feature = "wasm_simd", since = "1.54.0")]
    858pub fn i8x16_shuffle<
    859    const I0: usize,
    860    const I1: usize,
    861    const I2: usize,
    862    const I3: usize,
    863    const I4: usize,
    864    const I5: usize,
    865    const I6: usize,
    866    const I7: usize,
    867    const I8: usize,
    868    const I9: usize,
    869    const I10: usize,
    870    const I11: usize,
    871    const I12: usize,
    872    const I13: usize,
    873    const I14: usize,
    874    const I15: usize,
    875>(
    876    a: v128,
    877    b: v128,
    878) -> v128 {
    879    static_assert!(I0 < 32);
    880    static_assert!(I1 < 32);
    881    static_assert!(I2 < 32);
    882    static_assert!(I3 < 32);
    883    static_assert!(I4 < 32);
    884    static_assert!(I5 < 32);
    885    static_assert!(I6 < 32);
    886    static_assert!(I7 < 32);
    887    static_assert!(I8 < 32);
    888    static_assert!(I9 < 32);
    889    static_assert!(I10 < 32);
    890    static_assert!(I11 < 32);
    891    static_assert!(I12 < 32);
    892    static_assert!(I13 < 32);
    893    static_assert!(I14 < 32);
    894    static_assert!(I15 < 32);
    895    let shuf: simd::u8x16 = unsafe {
    896        simd_shuffle!(
    897            a.as_u8x16(),
    898            b.as_u8x16(),
    899            [
    900                I0 as u32, I1 as u32, I2 as u32, I3 as u32, I4 as u32, I5 as u32, I6 as u32,
    901                I7 as u32, I8 as u32, I9 as u32, I10 as u32, I11 as u32, I12 as u32, I13 as u32,
    902                I14 as u32, I15 as u32,
    903            ],
    904        )
    905    };
    906    shuf.v128()
    907}
    908
    909#[stable(feature = "wasm_simd", since = "1.54.0")]
    910pub use i8x16_shuffle as u8x16_shuffle;
    911
    912/// Same as [`i8x16_shuffle`], except operates as if the inputs were eight
    913/// 16-bit integers, only taking 8 indices to shuffle.
    914///
    915/// Indices in the range [0, 7] select from `a` while [8, 15] select from `b`.
    916/// Note that this will generate the `i8x16.shuffle` instruction, since there
    917/// is no native `i16x8.shuffle` instruction (there is no need for one since
    918/// `i8x16.shuffle` suffices).
    919#[inline]
    920#[cfg_attr(test,
    921    assert_instr(
    922        i8x16.shuffle,
    923        I0 = 0,
    924        I1 = 2,
    925        I2 = 4,
    926        I3 = 6,
    927        I4 = 8,
    928        I5 = 10,
    929        I6 = 12,
    930        I7 = 14,
    931    )
    932)]
    933#[target_feature(enable = "simd128")]
    934#[doc(alias("i8x16.shuffle"))]
    935#[stable(feature = "wasm_simd", since = "1.54.0")]
    936pub fn i16x8_shuffle<
    937    const I0: usize,
    938    const I1: usize,
    939    const I2: usize,
    940    const I3: usize,
    941    const I4: usize,
    942    const I5: usize,
    943    const I6: usize,
    944    const I7: usize,
    945>(
    946    a: v128,
    947    b: v128,
    948) -> v128 {
    949    static_assert!(I0 < 16);
    950    static_assert!(I1 < 16);
    951    static_assert!(I2 < 16);
    952    static_assert!(I3 < 16);
    953    static_assert!(I4 < 16);
    954    static_assert!(I5 < 16);
    955    static_assert!(I6 < 16);
    956    static_assert!(I7 < 16);
    957    let shuf: simd::u16x8 = unsafe {
    958        simd_shuffle!(
    959            a.as_u16x8(),
    960            b.as_u16x8(),
    961            [
    962                I0 as u32, I1 as u32, I2 as u32, I3 as u32, I4 as u32, I5 as u32, I6 as u32,
    963                I7 as u32,
    964            ],
    965        )
    966    };
    967    shuf.v128()
    968}
    969
    970#[stable(feature = "wasm_simd", since = "1.54.0")]
    971pub use i16x8_shuffle as u16x8_shuffle;
    972
    973/// Same as [`i8x16_shuffle`], except operates as if the inputs were four
    974/// 32-bit integers, only taking 4 indices to shuffle.
    975///
    976/// Indices in the range [0, 3] select from `a` while [4, 7] select from `b`.
    977/// Note that this will generate the `i8x16.shuffle` instruction, since there
    978/// is no native `i32x4.shuffle` instruction (there is no need for one since
    979/// `i8x16.shuffle` suffices).
    980#[inline]
    981#[cfg_attr(test, assert_instr(i8x16.shuffle, I0 = 0, I1 = 2, I2 = 4, I3 = 6))]
    982#[target_feature(enable = "simd128")]
    983#[doc(alias("i8x16.shuffle"))]
    984#[stable(feature = "wasm_simd", since = "1.54.0")]
    985pub fn i32x4_shuffle<const I0: usize, const I1: usize, const I2: usize, const I3: usize>(
    986    a: v128,
    987    b: v128,
    988) -> v128 {
    989    static_assert!(I0 < 8);
    990    static_assert!(I1 < 8);
    991    static_assert!(I2 < 8);
    992    static_assert!(I3 < 8);
    993    let shuf: simd::u32x4 = unsafe {
    994        simd_shuffle!(
    995            a.as_u32x4(),
    996            b.as_u32x4(),
    997            [I0 as u32, I1 as u32, I2 as u32, I3 as u32],
    998        )
    999    };
    1000    shuf.v128()
    1001}
    1002
    1003#[stable(feature = "wasm_simd", since = "1.54.0")]
    1004pub use i32x4_shuffle as u32x4_shuffle;
    1005
    1006/// Same as [`i8x16_shuffle`], except operates as if the inputs were two
    1007/// 64-bit integers, only taking 2 indices to shuffle.
    1008///
    1009/// Indices in the range [0, 1] select from `a` while [2, 3] select from `b`.
    1010/// Note that this will generate the `v8x16.shuffle` instruction, since there
    1011/// is no native `i64x2.shuffle` instruction (there is no need for one since
    1012/// `i8x16.shuffle` suffices).
    1013#[inline]
    1014#[cfg_attr(test, assert_instr(i8x16.shuffle, I0 = 0, I1 = 2))]
    1015#[target_feature(enable = "simd128")]
    1016#[doc(alias("i8x16.shuffle"))]
    1017#[stable(feature = "wasm_simd", since = "1.54.0")]
    1018pub fn i64x2_shuffle<const I0: usize, const I1: usize>(a: v128, b: v128) -> v128 {
    1019    static_assert!(I0 < 4);
    1020    static_assert!(I1 < 4);
    1021    let shuf: simd::u64x2 =
    1022        unsafe { simd_shuffle!(a.as_u64x2(), b.as_u64x2(), [I0 as u32, I1 as u32]) };
    1023    shuf.v128()
    1024}
    1025
    1026#[stable(feature = "wasm_simd", since = "1.54.0")]
    1027pub use i64x2_shuffle as u64x2_shuffle;
    1028
    1029/// Extracts a lane from a 128-bit vector interpreted as 16 packed i8 numbers.
    1030///
    1031/// Extracts the scalar value of lane specified in the immediate mode operand
    1032/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1033#[inline]
    1034#[cfg_attr(test, assert_instr(i8x16.extract_lane_s, N = 3))]
    1035#[target_feature(enable = "simd128")]
    1036#[doc(alias("i8x16.extract_lane_s"))]
    1037#[stable(feature = "wasm_simd", since = "1.54.0")]
    1038pub fn i8x16_extract_lane<const N: usize>(a: v128) -> i8 {
    1039    static_assert!(N < 16);
    1040    unsafe { simd_extract!(a.as_i8x16(), N as u32) }
    1041}
    1042
    1043/// Extracts a lane from a 128-bit vector interpreted as 16 packed u8 numbers.
    1044///
    1045/// Extracts the scalar value of lane specified in the immediate mode operand
    1046/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1047#[inline]
    1048#[cfg_attr(test, assert_instr(i8x16.extract_lane_u, N = 3))]
    1049#[target_feature(enable = "simd128")]
    1050#[doc(alias("i8x16.extract_lane_u"))]
    1051#[stable(feature = "wasm_simd", since = "1.54.0")]
    1052pub fn u8x16_extract_lane<const N: usize>(a: v128) -> u8 {
    1053    static_assert!(N < 16);
    1054    unsafe { simd_extract!(a.as_u8x16(), N as u32) }
    1055}
    1056
    1057/// Replaces a lane from a 128-bit vector interpreted as 16 packed i8 numbers.
    1058///
    1059/// Replaces the scalar value of lane specified in the immediate mode operand
    1060/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1061#[inline]
    1062#[cfg_attr(test, assert_instr(i8x16.replace_lane, N = 2))]
    1063#[target_feature(enable = "simd128")]
    1064#[doc(alias("i8x16.replace_lane"))]
    1065#[stable(feature = "wasm_simd", since = "1.54.0")]
    1066pub fn i8x16_replace_lane<const N: usize>(a: v128, val: i8) -> v128 {
    1067    static_assert!(N < 16);
    1068    unsafe { simd_insert!(a.as_i8x16(), N as u32, val).v128() }
    1069}
    1070
    1071/// Replaces a lane from a 128-bit vector interpreted as 16 packed u8 numbers.
    1072///
    1073/// Replaces the scalar value of lane specified in the immediate mode operand
    1074/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1075#[inline]
    1076#[cfg_attr(test, assert_instr(i8x16.replace_lane, N = 2))]
    1077#[target_feature(enable = "simd128")]
    1078#[doc(alias("i8x16.replace_lane"))]
    1079#[stable(feature = "wasm_simd", since = "1.54.0")]
    1080pub fn u8x16_replace_lane<const N: usize>(a: v128, val: u8) -> v128 {
    1081    static_assert!(N < 16);
    1082    unsafe { simd_insert!(a.as_u8x16(), N as u32, val).v128() }
    1083}
    1084
    1085/// Extracts a lane from a 128-bit vector interpreted as 8 packed i16 numbers.
    1086///
    1087/// Extracts a the scalar value of lane specified in the immediate mode operand
    1088/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1089#[inline]
    1090#[cfg_attr(test, assert_instr(i16x8.extract_lane_s, N = 2))]
    1091#[target_feature(enable = "simd128")]
    1092#[doc(alias("i16x8.extract_lane_s"))]
    1093#[stable(feature = "wasm_simd", since = "1.54.0")]
    1094pub fn i16x8_extract_lane<const N: usize>(a: v128) -> i16 {
    1095    static_assert!(N < 8);
    1096    unsafe { simd_extract!(a.as_i16x8(), N as u32) }
    1097}
    1098
    1099/// Extracts a lane from a 128-bit vector interpreted as 8 packed u16 numbers.
    1100///
    1101/// Extracts a the scalar value of lane specified in the immediate mode operand
    1102/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1103#[inline]
    1104#[cfg_attr(test, assert_instr(i16x8.extract_lane_u, N = 2))]
    1105#[target_feature(enable = "simd128")]
    1106#[doc(alias("i16x8.extract_lane_u"))]
    1107#[stable(feature = "wasm_simd", since = "1.54.0")]
    1108pub fn u16x8_extract_lane<const N: usize>(a: v128) -> u16 {
    1109    static_assert!(N < 8);
    1110    unsafe { simd_extract!(a.as_u16x8(), N as u32) }
    1111}
    1112
    1113/// Replaces a lane from a 128-bit vector interpreted as 8 packed i16 numbers.
    1114///
    1115/// Replaces the scalar value of lane specified in the immediate mode operand
    1116/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1117#[inline]
    1118#[cfg_attr(test, assert_instr(i16x8.replace_lane, N = 2))]
    1119#[target_feature(enable = "simd128")]
    1120#[doc(alias("i16x8.replace_lane"))]
    1121#[stable(feature = "wasm_simd", since = "1.54.0")]
    1122pub fn i16x8_replace_lane<const N: usize>(a: v128, val: i16) -> v128 {
    1123    static_assert!(N < 8);
    1124    unsafe { simd_insert!(a.as_i16x8(), N as u32, val).v128() }
    1125}
    1126
    1127/// Replaces a lane from a 128-bit vector interpreted as 8 packed u16 numbers.
    1128///
    1129/// Replaces the scalar value of lane specified in the immediate mode operand
    1130/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1131#[inline]
    1132#[cfg_attr(test, assert_instr(i16x8.replace_lane, N = 2))]
    1133#[target_feature(enable = "simd128")]
    1134#[doc(alias("i16x8.replace_lane"))]
    1135#[stable(feature = "wasm_simd", since = "1.54.0")]
    1136pub fn u16x8_replace_lane<const N: usize>(a: v128, val: u16) -> v128 {
    1137    static_assert!(N < 8);
    1138    unsafe { simd_insert!(a.as_u16x8(), N as u32, val).v128() }
    1139}
    1140
    1141/// Extracts a lane from a 128-bit vector interpreted as 4 packed i32 numbers.
    1142///
    1143/// Extracts the scalar value of lane specified in the immediate mode operand
    1144/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1145#[inline]
    1146#[cfg_attr(test, assert_instr(i32x4.extract_lane, N = 2))]
    1147#[target_feature(enable = "simd128")]
    1148#[doc(alias("i32x4.extract_lane"))]
    1149#[stable(feature = "wasm_simd", since = "1.54.0")]
    1150pub fn i32x4_extract_lane<const N: usize>(a: v128) -> i32 {
    1151    static_assert!(N < 4);
    1152    unsafe { simd_extract!(a.as_i32x4(), N as u32) }
    1153}
    1154
    1155/// Extracts a lane from a 128-bit vector interpreted as 4 packed u32 numbers.
    1156///
    1157/// Extracts the scalar value of lane specified in the immediate mode operand
    1158/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1159#[inline]
    1160#[target_feature(enable = "simd128")]
    1161#[doc(alias("i32x4.extract_lane"))]
    1162#[stable(feature = "wasm_simd", since = "1.54.0")]
    1163pub fn u32x4_extract_lane<const N: usize>(a: v128) -> u32 {
    1164    i32x4_extract_lane::<N>(a) as u32
    1165}
    1166
    1167/// Replaces a lane from a 128-bit vector interpreted as 4 packed i32 numbers.
    1168///
    1169/// Replaces the scalar value of lane specified in the immediate mode operand
    1170/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1171#[inline]
    1172#[cfg_attr(test, assert_instr(i32x4.replace_lane, N = 2))]
    1173#[target_feature(enable = "simd128")]
    1174#[doc(alias("i32x4.replace_lane"))]
    1175#[stable(feature = "wasm_simd", since = "1.54.0")]
    1176pub fn i32x4_replace_lane<const N: usize>(a: v128, val: i32) -> v128 {
    1177    static_assert!(N < 4);
    1178    unsafe { simd_insert!(a.as_i32x4(), N as u32, val).v128() }
    1179}
    1180
    1181/// Replaces a lane from a 128-bit vector interpreted as 4 packed u32 numbers.
    1182///
    1183/// Replaces the scalar value of lane specified in the immediate mode operand
    1184/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1185#[inline]
    1186#[target_feature(enable = "simd128")]
    1187#[doc(alias("i32x4.replace_lane"))]
    1188#[stable(feature = "wasm_simd", since = "1.54.0")]
    1189pub fn u32x4_replace_lane<const N: usize>(a: v128, val: u32) -> v128 {
    1190    i32x4_replace_lane::<N>(a, val as i32)
    1191}
    1192
    1193/// Extracts a lane from a 128-bit vector interpreted as 2 packed i64 numbers.
    1194///
    1195/// Extracts the scalar value of lane specified in the immediate mode operand
    1196/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1197#[inline]
    1198#[cfg_attr(test, assert_instr(i64x2.extract_lane, N = 1))]
    1199#[target_feature(enable = "simd128")]
    1200#[doc(alias("i64x2.extract_lane"))]
    1201#[stable(feature = "wasm_simd", since = "1.54.0")]
    1202pub fn i64x2_extract_lane<const N: usize>(a: v128) -> i64 {
    1203    static_assert!(N < 2);
    1204    unsafe { simd_extract!(a.as_i64x2(), N as u32) }
    1205}
    1206
    1207/// Extracts a lane from a 128-bit vector interpreted as 2 packed u64 numbers.
    1208///
    1209/// Extracts the scalar value of lane specified in the immediate mode operand
    1210/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1211#[inline]
    1212#[target_feature(enable = "simd128")]
    1213#[doc(alias("i64x2.extract_lane"))]
    1214#[stable(feature = "wasm_simd", since = "1.54.0")]
    1215pub fn u64x2_extract_lane<const N: usize>(a: v128) -> u64 {
    1216    i64x2_extract_lane::<N>(a) as u64
    1217}
    1218
    1219/// Replaces a lane from a 128-bit vector interpreted as 2 packed i64 numbers.
    1220///
    1221/// Replaces the scalar value of lane specified in the immediate mode operand
    1222/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1223#[inline]
    1224#[cfg_attr(test, assert_instr(i64x2.replace_lane, N = 0))]
    1225#[target_feature(enable = "simd128")]
    1226#[doc(alias("i64x2.replace_lane"))]
    1227#[stable(feature = "wasm_simd", since = "1.54.0")]
    1228pub fn i64x2_replace_lane<const N: usize>(a: v128, val: i64) -> v128 {
    1229    static_assert!(N < 2);
    1230    unsafe { simd_insert!(a.as_i64x2(), N as u32, val).v128() }
    1231}
    1232
    1233/// Replaces a lane from a 128-bit vector interpreted as 2 packed u64 numbers.
    1234///
    1235/// Replaces the scalar value of lane specified in the immediate mode operand
    1236/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1237#[inline]
    1238#[target_feature(enable = "simd128")]
    1239#[doc(alias("i64x2.replace_lane"))]
    1240#[stable(feature = "wasm_simd", since = "1.54.0")]
    1241pub fn u64x2_replace_lane<const N: usize>(a: v128, val: u64) -> v128 {
    1242    i64x2_replace_lane::<N>(a, val as i64)
    1243}
    1244
    1245/// Extracts a lane from a 128-bit vector interpreted as 4 packed f32 numbers.
    1246///
    1247/// Extracts the scalar value of lane specified fn the immediate mode operand
    1248/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1249#[inline]
    1250#[cfg_attr(test, assert_instr(f32x4.extract_lane, N = 1))]
    1251#[target_feature(enable = "simd128")]
    1252#[doc(alias("f32x4.extract_lane"))]
    1253#[stable(feature = "wasm_simd", since = "1.54.0")]
    1254pub fn f32x4_extract_lane<const N: usize>(a: v128) -> f32 {
    1255    static_assert!(N < 4);
    1256    unsafe { simd_extract!(a.as_f32x4(), N as u32) }
    1257}
    1258
    1259/// Replaces a lane from a 128-bit vector interpreted as 4 packed f32 numbers.
    1260///
    1261/// Replaces the scalar value of lane specified fn the immediate mode operand
    1262/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1263#[inline]
    1264#[cfg_attr(test, assert_instr(f32x4.replace_lane, N = 1))]
    1265#[target_feature(enable = "simd128")]
    1266#[doc(alias("f32x4.replace_lane"))]
    1267#[stable(feature = "wasm_simd", since = "1.54.0")]
    1268pub fn f32x4_replace_lane<const N: usize>(a: v128, val: f32) -> v128 {
    1269    static_assert!(N < 4);
    1270    unsafe { simd_insert!(a.as_f32x4(), N as u32, val).v128() }
    1271}
    1272
    1273/// Extracts a lane from a 128-bit vector interpreted as 2 packed f64 numbers.
    1274///
    1275/// Extracts the scalar value of lane specified fn the immediate mode operand
    1276/// `N` from `a`. If `N` fs out of bounds then it is a compile time error.
    1277#[inline]
    1278#[cfg_attr(test, assert_instr(f64x2.extract_lane, N = 1))]
    1279#[target_feature(enable = "simd128")]
    1280#[doc(alias("f64x2.extract_lane"))]
    1281#[stable(feature = "wasm_simd", since = "1.54.0")]
    1282pub fn f64x2_extract_lane<const N: usize>(a: v128) -> f64 {
    1283    static_assert!(N < 2);
    1284    unsafe { simd_extract!(a.as_f64x2(), N as u32) }
    1285}
    1286
    1287/// Replaces a lane from a 128-bit vector interpreted as 2 packed f64 numbers.
    1288///
    1289/// Replaces the scalar value of lane specified in the immediate mode operand
    1290/// `N` from `a`. If `N` is out of bounds then it is a compile time error.
    1291#[inline]
    1292#[cfg_attr(test, assert_instr(f64x2.replace_lane, N = 1))]
    1293#[target_feature(enable = "simd128")]
    1294#[doc(alias("f64x2.replace_lane"))]
    1295#[stable(feature = "wasm_simd", since = "1.54.0")]
    1296pub fn f64x2_replace_lane<const N: usize>(a: v128, val: f64) -> v128 {
    1297    static_assert!(N < 2);
    1298    unsafe { simd_insert!(a.as_f64x2(), N as u32, val).v128() }
    1299}
    1300
    1301/// Returns a new vector with lanes selected from the lanes of the first input
    1302/// vector `a` specified in the second input vector `s`.
    1303///
    1304/// The indices `i` in range [0, 15] select the `i`-th element of `a`. For
    1305/// indices outside of the range the resulting lane is 0.
    1306#[inline]
    1307#[cfg_attr(test, assert_instr(i8x16.swizzle))]
    1308#[target_feature(enable = "simd128")]
    1309#[doc(alias("i8x16.swizzle"))]
    1310#[stable(feature = "wasm_simd", since = "1.54.0")]
    1311pub fn i8x16_swizzle(a: v128, s: v128) -> v128 {
    1312    unsafe { llvm_swizzle(a.as_i8x16(), s.as_i8x16()).v128() }
    1313}
    1314
    1315#[stable(feature = "wasm_simd", since = "1.54.0")]
    1316pub use i8x16_swizzle as u8x16_swizzle;
    1317
    1318/// Creates a vector with identical lanes.
    1319///
    1320/// Constructs a vector with `x` replicated to all 16 lanes.
    1321#[inline]
    1322#[cfg_attr(test, assert_instr(i8x16.splat))]
    1323#[target_feature(enable = "simd128")]
    1324#[doc(alias("i8x16.splat"))]
    1325#[stable(feature = "wasm_simd", since = "1.54.0")]
    1326pub fn i8x16_splat(a: i8) -> v128 {
    1327    simd::i8x16::splat(a).v128()
    1328}
    1329
    1330/// Creates a vector with identical lanes.
    1331///
    1332/// Constructs a vector with `x` replicated to all 16 lanes.
    1333#[inline]
    1334#[cfg_attr(test, assert_instr(i8x16.splat))]
    1335#[target_feature(enable = "simd128")]
    1336#[doc(alias("i8x16.splat"))]
    1337#[stable(feature = "wasm_simd", since = "1.54.0")]
    1338pub fn u8x16_splat(a: u8) -> v128 {
    1339    simd::u8x16::splat(a).v128()
    1340}
    1341
    1342/// Creates a vector with identical lanes.
    1343///
    1344/// Construct a vector with `x` replicated to all 8 lanes.
    1345#[inline]
    1346#[cfg_attr(test, assert_instr(i16x8.splat))]
    1347#[target_feature(enable = "simd128")]
    1348#[doc(alias("i16x8.splat"))]
    1349#[stable(feature = "wasm_simd", since = "1.54.0")]
    1350pub fn i16x8_splat(a: i16) -> v128 {
    1351    simd::i16x8::splat(a).v128()
    1352}
    1353
    1354/// Creates a vector with identical lanes.
    1355///
    1356/// Construct a vector with `x` replicated to all 8 lanes.
    1357#[inline]
    1358#[cfg_attr(test, assert_instr(i16x8.splat))]
    1359#[target_feature(enable = "simd128")]
    1360#[doc(alias("i16x8.splat"))]
    1361#[stable(feature = "wasm_simd", since = "1.54.0")]
    1362pub fn u16x8_splat(a: u16) -> v128 {
    1363    simd::u16x8::splat(a).v128()
    1364}
    1365
    1366/// Creates a vector with identical lanes.
    1367///
    1368/// Constructs a vector with `x` replicated to all 4 lanes.
    1369#[inline]
    1370#[cfg_attr(test, assert_instr(i32x4.splat))]
    1371#[target_feature(enable = "simd128")]
    1372#[doc(alias("i32x4.splat"))]
    1373#[stable(feature = "wasm_simd", since = "1.54.0")]
    1374pub fn i32x4_splat(a: i32) -> v128 {
    1375    simd::i32x4::splat(a).v128()
    1376}
    1377
    1378/// Creates a vector with identical lanes.
    1379///
    1380/// Constructs a vector with `x` replicated to all 4 lanes.
    1381#[inline]
    1382#[target_feature(enable = "simd128")]
    1383#[doc(alias("i32x4.splat"))]
    1384#[stable(feature = "wasm_simd", since = "1.54.0")]
    1385pub fn u32x4_splat(a: u32) -> v128 {
    1386    i32x4_splat(a as i32)
    1387}
    1388
    1389/// Creates a vector with identical lanes.
    1390///
    1391/// Construct a vector with `x` replicated to all 2 lanes.
    1392#[inline]
    1393#[cfg_attr(test, assert_instr(i64x2.splat))]
    1394#[target_feature(enable = "simd128")]
    1395#[doc(alias("i64x2.splat"))]
    1396#[stable(feature = "wasm_simd", since = "1.54.0")]
    1397pub fn i64x2_splat(a: i64) -> v128 {
    1398    simd::i64x2::splat(a).v128()
    1399}
    1400
    1401/// Creates a vector with identical lanes.
    1402///
    1403/// Construct a vector with `x` replicated to all 2 lanes.
    1404#[inline]
    1405#[target_feature(enable = "simd128")]
    1406#[doc(alias("u64x2.splat"))]
    1407#[stable(feature = "wasm_simd", since = "1.54.0")]
    1408pub fn u64x2_splat(a: u64) -> v128 {
    1409    i64x2_splat(a as i64)
    1410}
    1411
    1412/// Creates a vector with identical lanes.
    1413///
    1414/// Constructs a vector with `x` replicated to all 4 lanes.
    1415#[inline]
    1416#[cfg_attr(test, assert_instr(f32x4.splat))]
    1417#[target_feature(enable = "simd128")]
    1418#[doc(alias("f32x4.splat"))]
    1419#[stable(feature = "wasm_simd", since = "1.54.0")]
    1420pub fn f32x4_splat(a: f32) -> v128 {
    1421    simd::f32x4::splat(a).v128()
    1422}
    1423
    1424/// Creates a vector with identical lanes.
    1425///
    1426/// Constructs a vector with `x` replicated to all 2 lanes.
    1427#[inline]
    1428#[cfg_attr(test, assert_instr(f64x2.splat))]
    1429#[target_feature(enable = "simd128")]
    1430#[doc(alias("f64x2.splat"))]
    1431#[stable(feature = "wasm_simd", since = "1.54.0")]
    1432pub fn f64x2_splat(a: f64) -> v128 {
    1433    simd::f64x2::splat(a).v128()
    1434}
    1435
    1436/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1437/// integers.
    1438///
    1439/// Returns a new vector where each lane is all ones if the corresponding input elements
    1440/// were equal, or all zeros otherwise.
    1441#[inline]
    1442#[cfg_attr(test, assert_instr(i8x16.eq))]
    1443#[target_feature(enable = "simd128")]
    1444#[doc(alias("i8x16.eq"))]
    1445#[stable(feature = "wasm_simd", since = "1.54.0")]
    1446pub fn i8x16_eq(a: v128, b: v128) -> v128 {
    1447    unsafe { simd_eq::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1448}
    1449
    1450/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1451/// integers.
    1452///
    1453/// Returns a new vector where each lane is all ones if the corresponding input elements
    1454/// were not equal, or all zeros otherwise.
    1455#[inline]
    1456#[cfg_attr(test, assert_instr(i8x16.ne))]
    1457#[target_feature(enable = "simd128")]
    1458#[doc(alias("i8x16.ne"))]
    1459#[stable(feature = "wasm_simd", since = "1.54.0")]
    1460pub fn i8x16_ne(a: v128, b: v128) -> v128 {
    1461    unsafe { simd_ne::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1462}
    1463
    1464#[stable(feature = "wasm_simd", since = "1.54.0")]
    1465pub use i8x16_eq as u8x16_eq;
    1466#[stable(feature = "wasm_simd", since = "1.54.0")]
    1467pub use i8x16_ne as u8x16_ne;
    1468
    1469/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1470/// signed integers.
    1471///
    1472/// Returns a new vector where each lane is all ones if the lane-wise left
    1473/// element is less than the right element, or all zeros otherwise.
    1474#[inline]
    1475#[cfg_attr(test, assert_instr(i8x16.lt_s))]
    1476#[target_feature(enable = "simd128")]
    1477#[doc(alias("i8x16.lt_s"))]
    1478#[stable(feature = "wasm_simd", since = "1.54.0")]
    1479pub fn i8x16_lt(a: v128, b: v128) -> v128 {
    1480    unsafe { simd_lt::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1481}
    1482
    1483/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1484/// unsigned integers.
    1485///
    1486/// Returns a new vector where each lane is all ones if the lane-wise left
    1487/// element is less than the right element, or all zeros otherwise.
    1488#[inline]
    1489#[cfg_attr(test, assert_instr(i8x16.lt_u))]
    1490#[target_feature(enable = "simd128")]
    1491#[doc(alias("i8x16.lt_u"))]
    1492#[stable(feature = "wasm_simd", since = "1.54.0")]
    1493pub fn u8x16_lt(a: v128, b: v128) -> v128 {
    1494    unsafe { simd_lt::<_, simd::i8x16>(a.as_u8x16(), b.as_u8x16()).v128() }
    1495}
    1496
    1497/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1498/// signed integers.
    1499///
    1500/// Returns a new vector where each lane is all ones if the lane-wise left
    1501/// element is greater than the right element, or all zeros otherwise.
    1502#[inline]
    1503#[cfg_attr(test, assert_instr(i8x16.gt_s))]
    1504#[target_feature(enable = "simd128")]
    1505#[doc(alias("i8x16.gt_s"))]
    1506#[stable(feature = "wasm_simd", since = "1.54.0")]
    1507pub fn i8x16_gt(a: v128, b: v128) -> v128 {
    1508    unsafe { simd_gt::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1509}
    1510
    1511/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1512/// unsigned integers.
    1513///
    1514/// Returns a new vector where each lane is all ones if the lane-wise left
    1515/// element is greater than the right element, or all zeros otherwise.
    1516#[inline]
    1517#[cfg_attr(test, assert_instr(i8x16.gt_u))]
    1518#[target_feature(enable = "simd128")]
    1519#[doc(alias("i8x16.gt_u"))]
    1520#[stable(feature = "wasm_simd", since = "1.54.0")]
    1521pub fn u8x16_gt(a: v128, b: v128) -> v128 {
    1522    unsafe { simd_gt::<_, simd::i8x16>(a.as_u8x16(), b.as_u8x16()).v128() }
    1523}
    1524
    1525/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1526/// signed integers.
    1527///
    1528/// Returns a new vector where each lane is all ones if the lane-wise left
    1529/// element is less than the right element, or all zeros otherwise.
    1530#[inline]
    1531#[cfg_attr(test, assert_instr(i8x16.le_s))]
    1532#[target_feature(enable = "simd128")]
    1533#[doc(alias("i8x16.le_s"))]
    1534#[stable(feature = "wasm_simd", since = "1.54.0")]
    1535pub fn i8x16_le(a: v128, b: v128) -> v128 {
    1536    unsafe { simd_le::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1537}
    1538
    1539/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1540/// unsigned integers.
    1541///
    1542/// Returns a new vector where each lane is all ones if the lane-wise left
    1543/// element is less than the right element, or all zeros otherwise.
    1544#[inline]
    1545#[cfg_attr(test, assert_instr(i8x16.le_u))]
    1546#[target_feature(enable = "simd128")]
    1547#[doc(alias("i8x16.le_u"))]
    1548#[stable(feature = "wasm_simd", since = "1.54.0")]
    1549pub fn u8x16_le(a: v128, b: v128) -> v128 {
    1550    unsafe { simd_le::<_, simd::i8x16>(a.as_u8x16(), b.as_u8x16()).v128() }
    1551}
    1552
    1553/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1554/// signed integers.
    1555///
    1556/// Returns a new vector where each lane is all ones if the lane-wise left
    1557/// element is greater than the right element, or all zeros otherwise.
    1558#[inline]
    1559#[cfg_attr(test, assert_instr(i8x16.ge_s))]
    1560#[target_feature(enable = "simd128")]
    1561#[doc(alias("i8x16.ge_s"))]
    1562#[stable(feature = "wasm_simd", since = "1.54.0")]
    1563pub fn i8x16_ge(a: v128, b: v128) -> v128 {
    1564    unsafe { simd_ge::<_, simd::i8x16>(a.as_i8x16(), b.as_i8x16()).v128() }
    1565}
    1566
    1567/// Compares two 128-bit vectors as if they were two vectors of 16 eight-bit
    1568/// unsigned integers.
    1569///
    1570/// Returns a new vector where each lane is all ones if the lane-wise left
    1571/// element is greater than the right element, or all zeros otherwise.
    1572#[inline]
    1573#[cfg_attr(test, assert_instr(i8x16.ge_u))]
    1574#[target_feature(enable = "simd128")]
    1575#[doc(alias("i8x16.ge_u"))]
    1576#[stable(feature = "wasm_simd", since = "1.54.0")]
    1577pub fn u8x16_ge(a: v128, b: v128) -> v128 {
    1578    unsafe { simd_ge::<_, simd::i8x16>(a.as_u8x16(), b.as_u8x16()).v128() }
    1579}
    1580
    1581/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1582/// integers.
    1583///
    1584/// Returns a new vector where each lane is all ones if the corresponding input elements
    1585/// were equal, or all zeros otherwise.
    1586#[inline]
    1587#[cfg_attr(test, assert_instr(i16x8.eq))]
    1588#[target_feature(enable = "simd128")]
    1589#[doc(alias("i16x8.eq"))]
    1590#[stable(feature = "wasm_simd", since = "1.54.0")]
    1591pub fn i16x8_eq(a: v128, b: v128) -> v128 {
    1592    unsafe { simd_eq::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1593}
    1594
    1595/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1596/// integers.
    1597///
    1598/// Returns a new vector where each lane is all ones if the corresponding input elements
    1599/// were not equal, or all zeros otherwise.
    1600#[inline]
    1601#[cfg_attr(test, assert_instr(i16x8.ne))]
    1602#[target_feature(enable = "simd128")]
    1603#[doc(alias("i16x8.ne"))]
    1604#[stable(feature = "wasm_simd", since = "1.54.0")]
    1605pub fn i16x8_ne(a: v128, b: v128) -> v128 {
    1606    unsafe { simd_ne::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1607}
    1608
    1609#[stable(feature = "wasm_simd", since = "1.54.0")]
    1610pub use i16x8_eq as u16x8_eq;
    1611#[stable(feature = "wasm_simd", since = "1.54.0")]
    1612pub use i16x8_ne as u16x8_ne;
    1613
    1614/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1615/// signed integers.
    1616///
    1617/// Returns a new vector where each lane is all ones if the lane-wise left
    1618/// element is less than the right element, or all zeros otherwise.
    1619#[inline]
    1620#[cfg_attr(test, assert_instr(i16x8.lt_s))]
    1621#[target_feature(enable = "simd128")]
    1622#[doc(alias("i16x8.lt_s"))]
    1623#[stable(feature = "wasm_simd", since = "1.54.0")]
    1624pub fn i16x8_lt(a: v128, b: v128) -> v128 {
    1625    unsafe { simd_lt::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1626}
    1627
    1628/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1629/// unsigned integers.
    1630///
    1631/// Returns a new vector where each lane is all ones if the lane-wise left
    1632/// element is less than the right element, or all zeros otherwise.
    1633#[inline]
    1634#[cfg_attr(test, assert_instr(i16x8.lt_u))]
    1635#[target_feature(enable = "simd128")]
    1636#[doc(alias("i16x8.lt_u"))]
    1637#[stable(feature = "wasm_simd", since = "1.54.0")]
    1638pub fn u16x8_lt(a: v128, b: v128) -> v128 {
    1639    unsafe { simd_lt::<_, simd::i16x8>(a.as_u16x8(), b.as_u16x8()).v128() }
    1640}
    1641
    1642/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1643/// signed integers.
    1644///
    1645/// Returns a new vector where each lane is all ones if the lane-wise left
    1646/// element is greater than the right element, or all zeros otherwise.
    1647#[inline]
    1648#[cfg_attr(test, assert_instr(i16x8.gt_s))]
    1649#[target_feature(enable = "simd128")]
    1650#[doc(alias("i16x8.gt_s"))]
    1651#[stable(feature = "wasm_simd", since = "1.54.0")]
    1652pub fn i16x8_gt(a: v128, b: v128) -> v128 {
    1653    unsafe { simd_gt::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1654}
    1655
    1656/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1657/// unsigned integers.
    1658///
    1659/// Returns a new vector where each lane is all ones if the lane-wise left
    1660/// element is greater than the right element, or all zeros otherwise.
    1661#[inline]
    1662#[cfg_attr(test, assert_instr(i16x8.gt_u))]
    1663#[target_feature(enable = "simd128")]
    1664#[doc(alias("i16x8.gt_u"))]
    1665#[stable(feature = "wasm_simd", since = "1.54.0")]
    1666pub fn u16x8_gt(a: v128, b: v128) -> v128 {
    1667    unsafe { simd_gt::<_, simd::i16x8>(a.as_u16x8(), b.as_u16x8()).v128() }
    1668}
    1669
    1670/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1671/// signed integers.
    1672///
    1673/// Returns a new vector where each lane is all ones if the lane-wise left
    1674/// element is less than the right element, or all zeros otherwise.
    1675#[inline]
    1676#[cfg_attr(test, assert_instr(i16x8.le_s))]
    1677#[target_feature(enable = "simd128")]
    1678#[doc(alias("i16x8.le_s"))]
    1679#[stable(feature = "wasm_simd", since = "1.54.0")]
    1680pub fn i16x8_le(a: v128, b: v128) -> v128 {
    1681    unsafe { simd_le::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1682}
    1683
    1684/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1685/// unsigned integers.
    1686///
    1687/// Returns a new vector where each lane is all ones if the lane-wise left
    1688/// element is less than the right element, or all zeros otherwise.
    1689#[inline]
    1690#[cfg_attr(test, assert_instr(i16x8.le_u))]
    1691#[target_feature(enable = "simd128")]
    1692#[doc(alias("i16x8.le_u"))]
    1693#[stable(feature = "wasm_simd", since = "1.54.0")]
    1694pub fn u16x8_le(a: v128, b: v128) -> v128 {
    1695    unsafe { simd_le::<_, simd::i16x8>(a.as_u16x8(), b.as_u16x8()).v128() }
    1696}
    1697
    1698/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1699/// signed integers.
    1700///
    1701/// Returns a new vector where each lane is all ones if the lane-wise left
    1702/// element is greater than the right element, or all zeros otherwise.
    1703#[inline]
    1704#[cfg_attr(test, assert_instr(i16x8.ge_s))]
    1705#[target_feature(enable = "simd128")]
    1706#[doc(alias("i16x8.ge_s"))]
    1707#[stable(feature = "wasm_simd", since = "1.54.0")]
    1708pub fn i16x8_ge(a: v128, b: v128) -> v128 {
    1709    unsafe { simd_ge::<_, simd::i16x8>(a.as_i16x8(), b.as_i16x8()).v128() }
    1710}
    1711
    1712/// Compares two 128-bit vectors as if they were two vectors of 8 sixteen-bit
    1713/// unsigned integers.
    1714///
    1715/// Returns a new vector where each lane is all ones if the lane-wise left
    1716/// element is greater than the right element, or all zeros otherwise.
    1717#[inline]
    1718#[cfg_attr(test, assert_instr(i16x8.ge_u))]
    1719#[target_feature(enable = "simd128")]
    1720#[doc(alias("i16x8.ge_u"))]
    1721#[stable(feature = "wasm_simd", since = "1.54.0")]
    1722pub fn u16x8_ge(a: v128, b: v128) -> v128 {
    1723    unsafe { simd_ge::<_, simd::i16x8>(a.as_u16x8(), b.as_u16x8()).v128() }
    1724}
    1725
    1726/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1727/// integers.
    1728///
    1729/// Returns a new vector where each lane is all ones if the corresponding input elements
    1730/// were equal, or all zeros otherwise.
    1731#[inline]
    1732#[cfg_attr(test, assert_instr(i32x4.eq))]
    1733#[target_feature(enable = "simd128")]
    1734#[doc(alias("i32x4.eq"))]
    1735#[stable(feature = "wasm_simd", since = "1.54.0")]
    1736pub fn i32x4_eq(a: v128, b: v128) -> v128 {
    1737    unsafe { simd_eq::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1738}
    1739
    1740/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1741/// integers.
    1742///
    1743/// Returns a new vector where each lane is all ones if the corresponding input elements
    1744/// were not equal, or all zeros otherwise.
    1745#[inline]
    1746#[cfg_attr(test, assert_instr(i32x4.ne))]
    1747#[target_feature(enable = "simd128")]
    1748#[doc(alias("i32x4.ne"))]
    1749#[stable(feature = "wasm_simd", since = "1.54.0")]
    1750pub fn i32x4_ne(a: v128, b: v128) -> v128 {
    1751    unsafe { simd_ne::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1752}
    1753
    1754#[stable(feature = "wasm_simd", since = "1.54.0")]
    1755pub use i32x4_eq as u32x4_eq;
    1756#[stable(feature = "wasm_simd", since = "1.54.0")]
    1757pub use i32x4_ne as u32x4_ne;
    1758
    1759/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1760/// signed integers.
    1761///
    1762/// Returns a new vector where each lane is all ones if the lane-wise left
    1763/// element is less than the right element, or all zeros otherwise.
    1764#[inline]
    1765#[cfg_attr(test, assert_instr(i32x4.lt_s))]
    1766#[target_feature(enable = "simd128")]
    1767#[doc(alias("i32x4.lt_s"))]
    1768#[stable(feature = "wasm_simd", since = "1.54.0")]
    1769pub fn i32x4_lt(a: v128, b: v128) -> v128 {
    1770    unsafe { simd_lt::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1771}
    1772
    1773/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1774/// unsigned integers.
    1775///
    1776/// Returns a new vector where each lane is all ones if the lane-wise left
    1777/// element is less than the right element, or all zeros otherwise.
    1778#[inline]
    1779#[cfg_attr(test, assert_instr(i32x4.lt_u))]
    1780#[target_feature(enable = "simd128")]
    1781#[doc(alias("i32x4.lt_u"))]
    1782#[stable(feature = "wasm_simd", since = "1.54.0")]
    1783pub fn u32x4_lt(a: v128, b: v128) -> v128 {
    1784    unsafe { simd_lt::<_, simd::i32x4>(a.as_u32x4(), b.as_u32x4()).v128() }
    1785}
    1786
    1787/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1788/// signed integers.
    1789///
    1790/// Returns a new vector where each lane is all ones if the lane-wise left
    1791/// element is greater than the right element, or all zeros otherwise.
    1792#[inline]
    1793#[cfg_attr(test, assert_instr(i32x4.gt_s))]
    1794#[target_feature(enable = "simd128")]
    1795#[doc(alias("i32x4.gt_s"))]
    1796#[stable(feature = "wasm_simd", since = "1.54.0")]
    1797pub fn i32x4_gt(a: v128, b: v128) -> v128 {
    1798    unsafe { simd_gt::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1799}
    1800
    1801/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1802/// unsigned integers.
    1803///
    1804/// Returns a new vector where each lane is all ones if the lane-wise left
    1805/// element is greater than the right element, or all zeros otherwise.
    1806#[inline]
    1807#[cfg_attr(test, assert_instr(i32x4.gt_u))]
    1808#[target_feature(enable = "simd128")]
    1809#[doc(alias("i32x4.gt_u"))]
    1810#[stable(feature = "wasm_simd", since = "1.54.0")]
    1811pub fn u32x4_gt(a: v128, b: v128) -> v128 {
    1812    unsafe { simd_gt::<_, simd::i32x4>(a.as_u32x4(), b.as_u32x4()).v128() }
    1813}
    1814
    1815/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1816/// signed integers.
    1817///
    1818/// Returns a new vector where each lane is all ones if the lane-wise left
    1819/// element is less than the right element, or all zeros otherwise.
    1820#[inline]
    1821#[cfg_attr(test, assert_instr(i32x4.le_s))]
    1822#[target_feature(enable = "simd128")]
    1823#[doc(alias("i32x4.le_s"))]
    1824#[stable(feature = "wasm_simd", since = "1.54.0")]
    1825pub fn i32x4_le(a: v128, b: v128) -> v128 {
    1826    unsafe { simd_le::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1827}
    1828
    1829/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1830/// unsigned integers.
    1831///
    1832/// Returns a new vector where each lane is all ones if the lane-wise left
    1833/// element is less than the right element, or all zeros otherwise.
    1834#[inline]
    1835#[cfg_attr(test, assert_instr(i32x4.le_u))]
    1836#[target_feature(enable = "simd128")]
    1837#[doc(alias("i32x4.le_u"))]
    1838#[stable(feature = "wasm_simd", since = "1.54.0")]
    1839pub fn u32x4_le(a: v128, b: v128) -> v128 {
    1840    unsafe { simd_le::<_, simd::i32x4>(a.as_u32x4(), b.as_u32x4()).v128() }
    1841}
    1842
    1843/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1844/// signed integers.
    1845///
    1846/// Returns a new vector where each lane is all ones if the lane-wise left
    1847/// element is greater than the right element, or all zeros otherwise.
    1848#[inline]
    1849#[cfg_attr(test, assert_instr(i32x4.ge_s))]
    1850#[target_feature(enable = "simd128")]
    1851#[doc(alias("i32x4.ge_s"))]
    1852#[stable(feature = "wasm_simd", since = "1.54.0")]
    1853pub fn i32x4_ge(a: v128, b: v128) -> v128 {
    1854    unsafe { simd_ge::<_, simd::i32x4>(a.as_i32x4(), b.as_i32x4()).v128() }
    1855}
    1856
    1857/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1858/// unsigned integers.
    1859///
    1860/// Returns a new vector where each lane is all ones if the lane-wise left
    1861/// element is greater than the right element, or all zeros otherwise.
    1862#[inline]
    1863#[cfg_attr(test, assert_instr(i32x4.ge_u))]
    1864#[target_feature(enable = "simd128")]
    1865#[doc(alias("i32x4.ge_u"))]
    1866#[stable(feature = "wasm_simd", since = "1.54.0")]
    1867pub fn u32x4_ge(a: v128, b: v128) -> v128 {
    1868    unsafe { simd_ge::<_, simd::i32x4>(a.as_u32x4(), b.as_u32x4()).v128() }
    1869}
    1870
    1871/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1872/// integers.
    1873///
    1874/// Returns a new vector where each lane is all ones if the corresponding input elements
    1875/// were equal, or all zeros otherwise.
    1876#[inline]
    1877#[cfg_attr(test, assert_instr(i64x2.eq))]
    1878#[target_feature(enable = "simd128")]
    1879#[doc(alias("i64x2.eq"))]
    1880#[stable(feature = "wasm_simd", since = "1.54.0")]
    1881pub fn i64x2_eq(a: v128, b: v128) -> v128 {
    1882    unsafe { simd_eq::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1883}
    1884
    1885/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1886/// integers.
    1887///
    1888/// Returns a new vector where each lane is all ones if the corresponding input elements
    1889/// were not equal, or all zeros otherwise.
    1890#[inline]
    1891#[cfg_attr(test, assert_instr(i64x2.ne))]
    1892#[target_feature(enable = "simd128")]
    1893#[doc(alias("i64x2.ne"))]
    1894#[stable(feature = "wasm_simd", since = "1.54.0")]
    1895pub fn i64x2_ne(a: v128, b: v128) -> v128 {
    1896    unsafe { simd_ne::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1897}
    1898
    1899#[stable(feature = "wasm_simd", since = "1.54.0")]
    1900pub use i64x2_eq as u64x2_eq;
    1901#[stable(feature = "wasm_simd", since = "1.54.0")]
    1902pub use i64x2_ne as u64x2_ne;
    1903
    1904/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1905/// signed integers.
    1906///
    1907/// Returns a new vector where each lane is all ones if the lane-wise left
    1908/// element is less than the right element, or all zeros otherwise.
    1909#[inline]
    1910#[cfg_attr(test, assert_instr(i64x2.lt_s))]
    1911#[target_feature(enable = "simd128")]
    1912#[doc(alias("i64x2.lt_s"))]
    1913#[stable(feature = "wasm_simd", since = "1.54.0")]
    1914pub fn i64x2_lt(a: v128, b: v128) -> v128 {
    1915    unsafe { simd_lt::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1916}
    1917
    1918/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1919/// signed integers.
    1920///
    1921/// Returns a new vector where each lane is all ones if the lane-wise left
    1922/// element is greater than the right element, or all zeros otherwise.
    1923#[inline]
    1924#[cfg_attr(test, assert_instr(i64x2.gt_s))]
    1925#[target_feature(enable = "simd128")]
    1926#[doc(alias("i64x2.gt_s"))]
    1927#[stable(feature = "wasm_simd", since = "1.54.0")]
    1928pub fn i64x2_gt(a: v128, b: v128) -> v128 {
    1929    unsafe { simd_gt::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1930}
    1931
    1932/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1933/// signed integers.
    1934///
    1935/// Returns a new vector where each lane is all ones if the lane-wise left
    1936/// element is less than the right element, or all zeros otherwise.
    1937#[inline]
    1938#[cfg_attr(test, assert_instr(i64x2.le_s))]
    1939#[target_feature(enable = "simd128")]
    1940#[doc(alias("i64x2.le_s"))]
    1941#[stable(feature = "wasm_simd", since = "1.54.0")]
    1942pub fn i64x2_le(a: v128, b: v128) -> v128 {
    1943    unsafe { simd_le::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1944}
    1945
    1946/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    1947/// signed integers.
    1948///
    1949/// Returns a new vector where each lane is all ones if the lane-wise left
    1950/// element is greater than the right element, or all zeros otherwise.
    1951#[inline]
    1952#[cfg_attr(test, assert_instr(i64x2.ge_s))]
    1953#[target_feature(enable = "simd128")]
    1954#[doc(alias("i64x2.ge_s"))]
    1955#[stable(feature = "wasm_simd", since = "1.54.0")]
    1956pub fn i64x2_ge(a: v128, b: v128) -> v128 {
    1957    unsafe { simd_ge::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()).v128() }
    1958}
    1959
    1960/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1961/// floating point numbers.
    1962///
    1963/// Returns a new vector where each lane is all ones if the corresponding input elements
    1964/// were equal, or all zeros otherwise.
    1965#[inline]
    1966#[cfg_attr(test, assert_instr(f32x4.eq))]
    1967#[target_feature(enable = "simd128")]
    1968#[doc(alias("f32x4.eq"))]
    1969#[stable(feature = "wasm_simd", since = "1.54.0")]
    1970pub fn f32x4_eq(a: v128, b: v128) -> v128 {
    1971    unsafe { simd_eq::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    1972}
    1973
    1974/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1975/// floating point numbers.
    1976///
    1977/// Returns a new vector where each lane is all ones if the corresponding input elements
    1978/// were not equal, or all zeros otherwise.
    1979#[inline]
    1980#[cfg_attr(test, assert_instr(f32x4.ne))]
    1981#[target_feature(enable = "simd128")]
    1982#[doc(alias("f32x4.ne"))]
    1983#[stable(feature = "wasm_simd", since = "1.54.0")]
    1984pub fn f32x4_ne(a: v128, b: v128) -> v128 {
    1985    unsafe { simd_ne::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    1986}
    1987
    1988/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    1989/// floating point numbers.
    1990///
    1991/// Returns a new vector where each lane is all ones if the lane-wise left
    1992/// element is less than the right element, or all zeros otherwise.
    1993#[inline]
    1994#[cfg_attr(test, assert_instr(f32x4.lt))]
    1995#[target_feature(enable = "simd128")]
    1996#[doc(alias("f32x4.lt"))]
    1997#[stable(feature = "wasm_simd", since = "1.54.0")]
    1998pub fn f32x4_lt(a: v128, b: v128) -> v128 {
    1999    unsafe { simd_lt::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    2000}
    2001
    2002/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    2003/// floating point numbers.
    2004///
    2005/// Returns a new vector where each lane is all ones if the lane-wise left
    2006/// element is greater than the right element, or all zeros otherwise.
    2007#[inline]
    2008#[cfg_attr(test, assert_instr(f32x4.gt))]
    2009#[target_feature(enable = "simd128")]
    2010#[doc(alias("f32x4.gt"))]
    2011#[stable(feature = "wasm_simd", since = "1.54.0")]
    2012pub fn f32x4_gt(a: v128, b: v128) -> v128 {
    2013    unsafe { simd_gt::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    2014}
    2015
    2016/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    2017/// floating point numbers.
    2018///
    2019/// Returns a new vector where each lane is all ones if the lane-wise left
    2020/// element is less than the right element, or all zeros otherwise.
    2021#[inline]
    2022#[cfg_attr(test, assert_instr(f32x4.le))]
    2023#[target_feature(enable = "simd128")]
    2024#[doc(alias("f32x4.le"))]
    2025#[stable(feature = "wasm_simd", since = "1.54.0")]
    2026pub fn f32x4_le(a: v128, b: v128) -> v128 {
    2027    unsafe { simd_le::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    2028}
    2029
    2030/// Compares two 128-bit vectors as if they were two vectors of 4 thirty-two-bit
    2031/// floating point numbers.
    2032///
    2033/// Returns a new vector where each lane is all ones if the lane-wise left
    2034/// element is greater than the right element, or all zeros otherwise.
    2035#[inline]
    2036#[cfg_attr(test, assert_instr(f32x4.ge))]
    2037#[target_feature(enable = "simd128")]
    2038#[doc(alias("f32x4.ge"))]
    2039#[stable(feature = "wasm_simd", since = "1.54.0")]
    2040pub fn f32x4_ge(a: v128, b: v128) -> v128 {
    2041    unsafe { simd_ge::<_, simd::i32x4>(a.as_f32x4(), b.as_f32x4()).v128() }
    2042}
    2043
    2044/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2045/// floating point numbers.
    2046///
    2047/// Returns a new vector where each lane is all ones if the corresponding input elements
    2048/// were equal, or all zeros otherwise.
    2049#[inline]
    2050#[cfg_attr(test, assert_instr(f64x2.eq))]
    2051#[target_feature(enable = "simd128")]
    2052#[doc(alias("f64x2.eq"))]
    2053#[stable(feature = "wasm_simd", since = "1.54.0")]
    2054pub fn f64x2_eq(a: v128, b: v128) -> v128 {
    2055    unsafe { simd_eq::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2056}
    2057
    2058/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2059/// floating point numbers.
    2060///
    2061/// Returns a new vector where each lane is all ones if the corresponding input elements
    2062/// were not equal, or all zeros otherwise.
    2063#[inline]
    2064#[cfg_attr(test, assert_instr(f64x2.ne))]
    2065#[target_feature(enable = "simd128")]
    2066#[doc(alias("f64x2.ne"))]
    2067#[stable(feature = "wasm_simd", since = "1.54.0")]
    2068pub fn f64x2_ne(a: v128, b: v128) -> v128 {
    2069    unsafe { simd_ne::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2070}
    2071
    2072/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2073/// floating point numbers.
    2074///
    2075/// Returns a new vector where each lane is all ones if the lane-wise left
    2076/// element is less than the right element, or all zeros otherwise.
    2077#[inline]
    2078#[cfg_attr(test, assert_instr(f64x2.lt))]
    2079#[target_feature(enable = "simd128")]
    2080#[doc(alias("f64x2.lt"))]
    2081#[stable(feature = "wasm_simd", since = "1.54.0")]
    2082pub fn f64x2_lt(a: v128, b: v128) -> v128 {
    2083    unsafe { simd_lt::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2084}
    2085
    2086/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2087/// floating point numbers.
    2088///
    2089/// Returns a new vector where each lane is all ones if the lane-wise left
    2090/// element is greater than the right element, or all zeros otherwise.
    2091#[inline]
    2092#[cfg_attr(test, assert_instr(f64x2.gt))]
    2093#[target_feature(enable = "simd128")]
    2094#[doc(alias("f64x2.gt"))]
    2095#[stable(feature = "wasm_simd", since = "1.54.0")]
    2096pub fn f64x2_gt(a: v128, b: v128) -> v128 {
    2097    unsafe { simd_gt::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2098}
    2099
    2100/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2101/// floating point numbers.
    2102///
    2103/// Returns a new vector where each lane is all ones if the lane-wise left
    2104/// element is less than the right element, or all zeros otherwise.
    2105#[inline]
    2106#[cfg_attr(test, assert_instr(f64x2.le))]
    2107#[target_feature(enable = "simd128")]
    2108#[doc(alias("f64x2.le"))]
    2109#[stable(feature = "wasm_simd", since = "1.54.0")]
    2110pub fn f64x2_le(a: v128, b: v128) -> v128 {
    2111    unsafe { simd_le::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2112}
    2113
    2114/// Compares two 128-bit vectors as if they were two vectors of 2 sixty-four-bit
    2115/// floating point numbers.
    2116///
    2117/// Returns a new vector where each lane is all ones if the lane-wise left
    2118/// element is greater than the right element, or all zeros otherwise.
    2119#[inline]
    2120#[cfg_attr(test, assert_instr(f64x2.ge))]
    2121#[target_feature(enable = "simd128")]
    2122#[doc(alias("f64x2.ge"))]
    2123#[stable(feature = "wasm_simd", since = "1.54.0")]
    2124pub fn f64x2_ge(a: v128, b: v128) -> v128 {
    2125    unsafe { simd_ge::<_, simd::i64x2>(a.as_f64x2(), b.as_f64x2()).v128() }
    2126}
    2127
    2128/// Flips each bit of the 128-bit input vector.
    2129#[inline]
    2130#[cfg_attr(test, assert_instr(v128.not))]
    2131#[target_feature(enable = "simd128")]
    2132#[doc(alias("v128.not"))]
    2133#[stable(feature = "wasm_simd", since = "1.54.0")]
    2134pub fn v128_not(a: v128) -> v128 {
    2135    unsafe { simd_xor(a.as_i64x2(), simd::i64x2::new(!0, !0)).v128() }
    2136}
    2137
    2138/// Performs a bitwise and of the two input 128-bit vectors, returning the
    2139/// resulting vector.
    2140#[inline]
    2141#[cfg_attr(test, assert_instr(v128.and))]
    2142#[target_feature(enable = "simd128")]
    2143#[doc(alias("v128.and"))]
    2144#[stable(feature = "wasm_simd", since = "1.54.0")]
    2145pub fn v128_and(a: v128, b: v128) -> v128 {
    2146    unsafe { simd_and(a.as_i64x2(), b.as_i64x2()).v128() }
    2147}
    2148
    2149/// Bitwise AND of bits of `a` and the logical inverse of bits of `b`.
    2150///
    2151/// This operation is equivalent to `v128.and(a, v128.not(b))`
    2152#[inline]
    2153#[cfg_attr(test, assert_instr(v128.andnot))]
    2154#[target_feature(enable = "simd128")]
    2155#[doc(alias("v128.andnot"))]
    2156#[stable(feature = "wasm_simd", since = "1.54.0")]
    2157pub fn v128_andnot(a: v128, b: v128) -> v128 {
    2158    unsafe {
    2159        simd_and(
    2160            a.as_i64x2(),
    2161            simd_xor(b.as_i64x2(), simd::i64x2::new(-1, -1)),
    2162        )
    2163        .v128()
    2164    }
    2165}
    2166
    2167/// Performs a bitwise or of the two input 128-bit vectors, returning the
    2168/// resulting vector.
    2169#[inline]
    2170#[cfg_attr(test, assert_instr(v128.or))]
    2171#[target_feature(enable = "simd128")]
    2172#[doc(alias("v128.or"))]
    2173#[stable(feature = "wasm_simd", since = "1.54.0")]
    2174pub fn v128_or(a: v128, b: v128) -> v128 {
    2175    unsafe { simd_or(a.as_i64x2(), b.as_i64x2()).v128() }
    2176}
    2177
    2178/// Performs a bitwise xor of the two input 128-bit vectors, returning the
    2179/// resulting vector.
    2180#[inline]
    2181#[cfg_attr(test, assert_instr(v128.xor))]
    2182#[target_feature(enable = "simd128")]
    2183#[doc(alias("v128.xor"))]
    2184#[stable(feature = "wasm_simd", since = "1.54.0")]
    2185pub fn v128_xor(a: v128, b: v128) -> v128 {
    2186    unsafe { simd_xor(a.as_i64x2(), b.as_i64x2()).v128() }
    2187}
    2188
    2189/// Use the bitmask in `c` to select bits from `v1` when 1 and `v2` when 0.
    2190#[inline]
    2191#[cfg_attr(test, assert_instr(v128.bitselect))]
    2192#[target_feature(enable = "simd128")]
    2193#[doc(alias("v128.bitselect"))]
    2194#[stable(feature = "wasm_simd", since = "1.54.0")]
    2195pub fn v128_bitselect(v1: v128, v2: v128, c: v128) -> v128 {
    2196    unsafe { llvm_bitselect(v1.as_i8x16(), v2.as_i8x16(), c.as_i8x16()).v128() }
    2197}
    2198
    2199/// Returns `true` if any bit in `a` is set, or `false` otherwise.
    2200#[inline]
    2201#[cfg_attr(test, assert_instr(v128.any_true))]
    2202#[target_feature(enable = "simd128")]
    2203#[doc(alias("v128.any_true"))]
    2204#[stable(feature = "wasm_simd", since = "1.54.0")]
    2205pub fn v128_any_true(a: v128) -> bool {
    2206    unsafe { llvm_any_true_i8x16(a.as_i8x16()) != 0 }
    2207}
    2208
    2209/// Lane-wise wrapping absolute value.
    2210#[inline]
    2211#[cfg_attr(test, assert_instr(i8x16.abs))]
    2212#[target_feature(enable = "simd128")]
    2213#[doc(alias("i8x16.abs"))]
    2214#[stable(feature = "wasm_simd", since = "1.54.0")]
    2215pub fn i8x16_abs(a: v128) -> v128 {
    2216    unsafe {
    2217        let a = a.as_i8x16();
    2218        let zero = simd::i8x16::ZERO;
    2219        simd_select::<simd::m8x16, simd::i8x16>(simd_lt(a, zero), simd_sub(zero, a), a).v128()
    2220    }
    2221}
    2222
    2223/// Negates a 128-bit vectors interpreted as sixteen 8-bit signed integers
    2224#[inline]
    2225#[cfg_attr(test, assert_instr(i8x16.neg))]
    2226#[target_feature(enable = "simd128")]
    2227#[doc(alias("i8x16.neg"))]
    2228#[stable(feature = "wasm_simd", since = "1.54.0")]
    2229pub fn i8x16_neg(a: v128) -> v128 {
    2230    unsafe { simd_mul(a.as_i8x16(), simd::i8x16::splat(-1)).v128() }
    2231}
    2232
    2233/// Count the number of bits set to one within each lane.
    2234#[inline]
    2235#[cfg_attr(test, assert_instr(i8x16.popcnt))]
    2236#[target_feature(enable = "simd128")]
    2237#[doc(alias("i8x16.popcnt"))]
    2238#[stable(feature = "wasm_simd", since = "1.54.0")]
    2239pub fn i8x16_popcnt(v: v128) -> v128 {
    2240    unsafe { simd_ctpop(v.as_i8x16()).v128() }
    2241}
    2242
    2243#[stable(feature = "wasm_simd", since = "1.54.0")]
    2244pub use i8x16_popcnt as u8x16_popcnt;
    2245
    2246/// Returns true if all lanes are non-zero, false otherwise.
    2247#[inline]
    2248#[cfg_attr(test, assert_instr(i8x16.all_true))]
    2249#[target_feature(enable = "simd128")]
    2250#[doc(alias("i8x16.all_true"))]
    2251#[stable(feature = "wasm_simd", since = "1.54.0")]
    2252pub fn i8x16_all_true(a: v128) -> bool {
    2253    unsafe { llvm_i8x16_all_true(a.as_i8x16()) != 0 }
    2254}
    2255
    2256#[stable(feature = "wasm_simd", since = "1.54.0")]
    2257pub use i8x16_all_true as u8x16_all_true;
    2258
    2259/// Extracts the high bit for each lane in `a` and produce a scalar mask with
    2260/// all bits concatenated.
    2261#[inline]
    2262#[cfg_attr(test, assert_instr(i8x16.bitmask))]
    2263#[target_feature(enable = "simd128")]
    2264#[doc(alias("i8x16.bitmask"))]
    2265#[stable(feature = "wasm_simd", since = "1.54.0")]
    2266pub fn i8x16_bitmask(a: v128) -> u16 {
    2267    unsafe { llvm_bitmask_i8x16(a.as_i8x16()) as u16 }
    2268}
    2269
    2270#[stable(feature = "wasm_simd", since = "1.54.0")]
    2271pub use i8x16_bitmask as u8x16_bitmask;
    2272
    2273/// Converts two input vectors into a smaller lane vector by narrowing each
    2274/// lane.
    2275///
    2276/// Signed saturation to 0x7f or 0x80 is used and the input lanes are always
    2277/// interpreted as signed integers.
    2278#[inline]
    2279#[cfg_attr(test, assert_instr(i8x16.narrow_i16x8_s))]
    2280#[target_feature(enable = "simd128")]
    2281#[doc(alias("i8x16.narrow_i16x8_s"))]
    2282#[stable(feature = "wasm_simd", since = "1.54.0")]
    2283pub fn i8x16_narrow_i16x8(a: v128, b: v128) -> v128 {
    2284    unsafe { llvm_narrow_i8x16_s(a.as_i16x8(), b.as_i16x8()).v128() }
    2285}
    2286
    2287/// Converts two input vectors into a smaller lane vector by narrowing each
    2288/// lane.
    2289///
    2290/// Signed saturation to 0x00 or 0xff is used and the input lanes are always
    2291/// interpreted as signed integers.
    2292#[inline]
    2293#[cfg_attr(test, assert_instr(i8x16.narrow_i16x8_u))]
    2294#[target_feature(enable = "simd128")]
    2295#[doc(alias("i8x16.narrow_i16x8_u"))]
    2296#[stable(feature = "wasm_simd", since = "1.54.0")]
    2297pub fn u8x16_narrow_i16x8(a: v128, b: v128) -> v128 {
    2298    unsafe { llvm_narrow_i8x16_u(a.as_i16x8(), b.as_i16x8()).v128() }
    2299}
    2300
    2301/// Shifts each lane to the left by the specified number of bits.
    2302///
    2303/// Only the low bits of the shift amount are used if the shift amount is
    2304/// greater than the lane width.
    2305#[inline]
    2306#[cfg_attr(test, assert_instr(i8x16.shl))]
    2307#[target_feature(enable = "simd128")]
    2308#[doc(alias("i8x16.shl"))]
    2309#[stable(feature = "wasm_simd", since = "1.54.0")]
    2310pub fn i8x16_shl(a: v128, amt: u32) -> v128 {
    2311    // SAFETY: the safety of this intrinsic relies on the fact that the
    2312    // shift amount for each lane is less than the number of bits in the input
    2313    // lane. In this case the input has 8-bit lanes but the shift amount above
    2314    // is `u32`, so a mask is required to discard all the upper bits of `amt` to
    2315    // ensure that the safety condition is met.
    2316    //
    2317    // Note that this is distinct from the behavior of the native WebAssembly
    2318    // instruction here where WebAssembly defines this instruction as performing
    2319    // a mask as well. This is nonetheless required since this must have defined
    2320    // semantics in LLVM, not just WebAssembly.
    2321    //
    2322    // Finally note that this mask operation is not actually emitted into the
    2323    // final binary itself. LLVM understands that the wasm operation implicitly
    2324    // masks, so it knows this mask operation is redundant.
    2325    //
    2326    // Basically the extra mask here is required as a bridge from the documented
    2327    // semantics through LLVM back out to WebAssembly. Both ends have the
    2328    // documented semantics, and the mask is required by LLVM in the middle.
    2329    unsafe { simd_shl(a.as_i8x16(), simd::i8x16::splat((amt & 0x7) as i8)).v128() }
    2330}
    2331
    2332#[stable(feature = "wasm_simd", since = "1.54.0")]
    2333pub use i8x16_shl as u8x16_shl;
    2334
    2335/// Shifts each lane to the right by the specified number of bits, sign
    2336/// extending.
    2337///
    2338/// Only the low bits of the shift amount are used if the shift amount is
    2339/// greater than the lane width.
    2340#[inline]
    2341#[cfg_attr(test, assert_instr(i8x16.shr_s))]
    2342#[target_feature(enable = "simd128")]
    2343#[doc(alias("i8x16.shr_s"))]
    2344#[stable(feature = "wasm_simd", since = "1.54.0")]
    2345pub fn i8x16_shr(a: v128, amt: u32) -> v128 {
    2346    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    2347    // essentially the shift amount must be valid hence the mask.
    2348    unsafe { simd_shr(a.as_i8x16(), simd::i8x16::splat((amt & 0x7) as i8)).v128() }
    2349}
    2350
    2351/// Shifts each lane to the right by the specified number of bits, shifting in
    2352/// zeros.
    2353///
    2354/// Only the low bits of the shift amount are used if the shift amount is
    2355/// greater than the lane width.
    2356#[inline]
    2357#[cfg_attr(test, assert_instr(i8x16.shr_u))]
    2358#[target_feature(enable = "simd128")]
    2359#[doc(alias("i8x16.shr_u"))]
    2360#[stable(feature = "wasm_simd", since = "1.54.0")]
    2361pub fn u8x16_shr(a: v128, amt: u32) -> v128 {
    2362    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    2363    // essentially the shift amount must be valid hence the mask.
    2364    unsafe { simd_shr(a.as_u8x16(), simd::u8x16::splat((amt & 0x7) as u8)).v128() }
    2365}
    2366
    2367/// Adds two 128-bit vectors as if they were two packed sixteen 8-bit integers.
    2368#[inline]
    2369#[cfg_attr(test, assert_instr(i8x16.add))]
    2370#[target_feature(enable = "simd128")]
    2371#[doc(alias("i8x16.add"))]
    2372#[stable(feature = "wasm_simd", since = "1.54.0")]
    2373pub fn i8x16_add(a: v128, b: v128) -> v128 {
    2374    unsafe { simd_add(a.as_i8x16(), b.as_i8x16()).v128() }
    2375}
    2376
    2377#[stable(feature = "wasm_simd", since = "1.54.0")]
    2378pub use i8x16_add as u8x16_add;
    2379
    2380/// Adds two 128-bit vectors as if they were two packed sixteen 8-bit signed
    2381/// integers, saturating on overflow to `i8::MAX`.
    2382#[inline]
    2383#[cfg_attr(test, assert_instr(i8x16.add_sat_s))]
    2384#[target_feature(enable = "simd128")]
    2385#[doc(alias("i8x16.add_sat_s"))]
    2386#[stable(feature = "wasm_simd", since = "1.54.0")]
    2387pub fn i8x16_add_sat(a: v128, b: v128) -> v128 {
    2388    unsafe { simd_saturating_add(a.as_i8x16(), b.as_i8x16()).v128() }
    2389}
    2390
    2391/// Adds two 128-bit vectors as if they were two packed sixteen 8-bit unsigned
    2392/// integers, saturating on overflow to `u8::MAX`.
    2393#[inline]
    2394#[cfg_attr(test, assert_instr(i8x16.add_sat_u))]
    2395#[target_feature(enable = "simd128")]
    2396#[doc(alias("i8x16.add_sat_u"))]
    2397#[stable(feature = "wasm_simd", since = "1.54.0")]
    2398pub fn u8x16_add_sat(a: v128, b: v128) -> v128 {
    2399    unsafe { simd_saturating_add(a.as_u8x16(), b.as_u8x16()).v128() }
    2400}
    2401
    2402/// Subtracts two 128-bit vectors as if they were two packed sixteen 8-bit integers.
    2403#[inline]
    2404#[cfg_attr(test, assert_instr(i8x16.sub))]
    2405#[target_feature(enable = "simd128")]
    2406#[doc(alias("i8x16.sub"))]
    2407#[stable(feature = "wasm_simd", since = "1.54.0")]
    2408pub fn i8x16_sub(a: v128, b: v128) -> v128 {
    2409    unsafe { simd_sub(a.as_i8x16(), b.as_i8x16()).v128() }
    2410}
    2411
    2412#[stable(feature = "wasm_simd", since = "1.54.0")]
    2413pub use i8x16_sub as u8x16_sub;
    2414
    2415/// Subtracts two 128-bit vectors as if they were two packed sixteen 8-bit
    2416/// signed integers, saturating on overflow to `i8::MIN`.
    2417#[inline]
    2418#[cfg_attr(test, assert_instr(i8x16.sub_sat_s))]
    2419#[target_feature(enable = "simd128")]
    2420#[doc(alias("i8x16.sub_sat_s"))]
    2421#[stable(feature = "wasm_simd", since = "1.54.0")]
    2422pub fn i8x16_sub_sat(a: v128, b: v128) -> v128 {
    2423    unsafe { simd_saturating_sub(a.as_i8x16(), b.as_i8x16()).v128() }
    2424}
    2425
    2426/// Subtracts two 128-bit vectors as if they were two packed sixteen 8-bit
    2427/// unsigned integers, saturating on overflow to 0.
    2428#[inline]
    2429#[cfg_attr(test, assert_instr(i8x16.sub_sat_u))]
    2430#[target_feature(enable = "simd128")]
    2431#[doc(alias("i8x16.sub_sat_u"))]
    2432#[stable(feature = "wasm_simd", since = "1.54.0")]
    2433pub fn u8x16_sub_sat(a: v128, b: v128) -> v128 {
    2434    unsafe { simd_saturating_sub(a.as_u8x16(), b.as_u8x16()).v128() }
    2435}
    2436
    2437/// Compares lane-wise signed integers, and returns the minimum of
    2438/// each pair.
    2439#[inline]
    2440#[cfg_attr(test, assert_instr(i8x16.min_s))]
    2441#[target_feature(enable = "simd128")]
    2442#[doc(alias("i8x16.min_s"))]
    2443#[stable(feature = "wasm_simd", since = "1.54.0")]
    2444pub fn i8x16_min(a: v128, b: v128) -> v128 {
    2445    let a = a.as_i8x16();
    2446    let b = b.as_i8x16();
    2447    unsafe { simd_select::<simd::i8x16, _>(simd_lt(a, b), a, b).v128() }
    2448}
    2449
    2450/// Compares lane-wise unsigned integers, and returns the minimum of
    2451/// each pair.
    2452#[inline]
    2453#[cfg_attr(test, assert_instr(i8x16.min_u))]
    2454#[target_feature(enable = "simd128")]
    2455#[doc(alias("i8x16.min_u"))]
    2456#[stable(feature = "wasm_simd", since = "1.54.0")]
    2457pub fn u8x16_min(a: v128, b: v128) -> v128 {
    2458    let a = a.as_u8x16();
    2459    let b = b.as_u8x16();
    2460    unsafe { simd_select::<simd::i8x16, _>(simd_lt(a, b), a, b).v128() }
    2461}
    2462
    2463/// Compares lane-wise signed integers, and returns the maximum of
    2464/// each pair.
    2465#[inline]
    2466#[cfg_attr(test, assert_instr(i8x16.max_s))]
    2467#[target_feature(enable = "simd128")]
    2468#[doc(alias("i8x16.max_s"))]
    2469#[stable(feature = "wasm_simd", since = "1.54.0")]
    2470pub fn i8x16_max(a: v128, b: v128) -> v128 {
    2471    let a = a.as_i8x16();
    2472    let b = b.as_i8x16();
    2473    unsafe { simd_select::<simd::i8x16, _>(simd_gt(a, b), a, b).v128() }
    2474}
    2475
    2476/// Compares lane-wise unsigned integers, and returns the maximum of
    2477/// each pair.
    2478#[inline]
    2479#[cfg_attr(test, assert_instr(i8x16.max_u))]
    2480#[target_feature(enable = "simd128")]
    2481#[doc(alias("i8x16.max_u"))]
    2482#[stable(feature = "wasm_simd", since = "1.54.0")]
    2483pub fn u8x16_max(a: v128, b: v128) -> v128 {
    2484    let a = a.as_u8x16();
    2485    let b = b.as_u8x16();
    2486    unsafe { simd_select::<simd::i8x16, _>(simd_gt(a, b), a, b).v128() }
    2487}
    2488
    2489/// Lane-wise rounding average.
    2490#[inline]
    2491#[cfg_attr(test, assert_instr(i8x16.avgr_u))]
    2492#[target_feature(enable = "simd128")]
    2493#[doc(alias("i8x16.avgr_u"))]
    2494#[stable(feature = "wasm_simd", since = "1.54.0")]
    2495pub fn u8x16_avgr(a: v128, b: v128) -> v128 {
    2496    unsafe { llvm_avgr_u_i8x16(a.as_i8x16(), b.as_i8x16()).v128() }
    2497}
    2498
    2499/// Integer extended pairwise addition producing extended results
    2500/// (twice wider results than the inputs).
    2501#[inline]
    2502#[cfg_attr(test, assert_instr(i16x8.extadd_pairwise_i8x16_s))]
    2503#[target_feature(enable = "simd128")]
    2504#[doc(alias("i16x8.extadd_pairwise_i8x16_s"))]
    2505#[stable(feature = "wasm_simd", since = "1.54.0")]
    2506pub fn i16x8_extadd_pairwise_i8x16(a: v128) -> v128 {
    2507    unsafe { llvm_i16x8_extadd_pairwise_i8x16_s(a.as_i8x16()).v128() }
    2508}
    2509
    2510/// Integer extended pairwise addition producing extended results
    2511/// (twice wider results than the inputs).
    2512#[inline]
    2513#[cfg_attr(test, assert_instr(i16x8.extadd_pairwise_i8x16_u))]
    2514#[target_feature(enable = "simd128")]
    2515#[doc(alias("i16x8.extadd_pairwise_i8x16_u"))]
    2516#[stable(feature = "wasm_simd", since = "1.54.0")]
    2517pub fn i16x8_extadd_pairwise_u8x16(a: v128) -> v128 {
    2518    unsafe { llvm_i16x8_extadd_pairwise_i8x16_u(a.as_i8x16()).v128() }
    2519}
    2520
    2521#[stable(feature = "wasm_simd", since = "1.54.0")]
    2522pub use i16x8_extadd_pairwise_u8x16 as u16x8_extadd_pairwise_u8x16;
    2523
    2524/// Lane-wise wrapping absolute value.
    2525#[inline]
    2526#[cfg_attr(test, assert_instr(i16x8.abs))]
    2527#[target_feature(enable = "simd128")]
    2528#[doc(alias("i16x8.abs"))]
    2529#[stable(feature = "wasm_simd", since = "1.54.0")]
    2530pub fn i16x8_abs(a: v128) -> v128 {
    2531    let a = a.as_i16x8();
    2532    let zero = simd::i16x8::ZERO;
    2533    unsafe {
    2534        simd_select::<simd::m16x8, simd::i16x8>(simd_lt(a, zero), simd_sub(zero, a), a).v128()
    2535    }
    2536}
    2537
    2538/// Negates a 128-bit vectors interpreted as eight 16-bit signed integers
    2539#[inline]
    2540#[cfg_attr(test, assert_instr(i16x8.neg))]
    2541#[target_feature(enable = "simd128")]
    2542#[doc(alias("i16x8.neg"))]
    2543#[stable(feature = "wasm_simd", since = "1.54.0")]
    2544pub fn i16x8_neg(a: v128) -> v128 {
    2545    unsafe { simd_mul(a.as_i16x8(), simd::i16x8::splat(-1)).v128() }
    2546}
    2547
    2548/// Lane-wise saturating rounding multiplication in Q15 format.
    2549#[inline]
    2550#[cfg_attr(test, assert_instr(i16x8.q15mulr_sat_s))]
    2551#[target_feature(enable = "simd128")]
    2552#[doc(alias("i16x8.q15mulr_sat_s"))]
    2553#[stable(feature = "wasm_simd", since = "1.54.0")]
    2554pub fn i16x8_q15mulr_sat(a: v128, b: v128) -> v128 {
    2555    unsafe { llvm_q15mulr(a.as_i16x8(), b.as_i16x8()).v128() }
    2556}
    2557
    2558/// Returns true if all lanes are non-zero, false otherwise.
    2559#[inline]
    2560#[cfg_attr(test, assert_instr(i16x8.all_true))]
    2561#[target_feature(enable = "simd128")]
    2562#[doc(alias("i16x8.all_true"))]
    2563#[stable(feature = "wasm_simd", since = "1.54.0")]
    2564pub fn i16x8_all_true(a: v128) -> bool {
    2565    unsafe { llvm_i16x8_all_true(a.as_i16x8()) != 0 }
    2566}
    2567
    2568#[stable(feature = "wasm_simd", since = "1.54.0")]
    2569pub use i16x8_all_true as u16x8_all_true;
    2570
    2571/// Extracts the high bit for each lane in `a` and produce a scalar mask with
    2572/// all bits concatenated.
    2573#[inline]
    2574#[cfg_attr(test, assert_instr(i16x8.bitmask))]
    2575#[target_feature(enable = "simd128")]
    2576#[doc(alias("i16x8.bitmask"))]
    2577#[stable(feature = "wasm_simd", since = "1.54.0")]
    2578pub fn i16x8_bitmask(a: v128) -> u8 {
    2579    unsafe { llvm_bitmask_i16x8(a.as_i16x8()) as u8 }
    2580}
    2581
    2582#[stable(feature = "wasm_simd", since = "1.54.0")]
    2583pub use i16x8_bitmask as u16x8_bitmask;
    2584
    2585/// Converts two input vectors into a smaller lane vector by narrowing each
    2586/// lane.
    2587///
    2588/// Signed saturation to 0x7fff or 0x8000 is used and the input lanes are always
    2589/// interpreted as signed integers.
    2590#[inline]
    2591#[cfg_attr(test, assert_instr(i16x8.narrow_i32x4_s))]
    2592#[target_feature(enable = "simd128")]
    2593#[doc(alias("i16x8.narrow_i32x4_s"))]
    2594#[stable(feature = "wasm_simd", since = "1.54.0")]
    2595pub fn i16x8_narrow_i32x4(a: v128, b: v128) -> v128 {
    2596    unsafe { llvm_narrow_i16x8_s(a.as_i32x4(), b.as_i32x4()).v128() }
    2597}
    2598
    2599/// Converts two input vectors into a smaller lane vector by narrowing each
    2600/// lane.
    2601///
    2602/// Signed saturation to 0x0000 or 0xffff is used and the input lanes are always
    2603/// interpreted as signed integers.
    2604#[inline]
    2605#[cfg_attr(test, assert_instr(i16x8.narrow_i32x4_u))]
    2606#[target_feature(enable = "simd128")]
    2607#[doc(alias("i16x8.narrow_i32x4_u"))]
    2608#[stable(feature = "wasm_simd", since = "1.54.0")]
    2609pub fn u16x8_narrow_i32x4(a: v128, b: v128) -> v128 {
    2610    unsafe { llvm_narrow_i16x8_u(a.as_i32x4(), b.as_i32x4()).v128() }
    2611}
    2612
    2613/// Converts low half of the smaller lane vector to a larger lane
    2614/// vector, sign extended.
    2615#[inline]
    2616#[cfg_attr(test, assert_instr(i16x8.extend_low_i8x16_s))]
    2617#[target_feature(enable = "simd128")]
    2618#[doc(alias("i16x8.extend_low_i8x16_s"))]
    2619#[stable(feature = "wasm_simd", since = "1.54.0")]
    2620pub fn i16x8_extend_low_i8x16(a: v128) -> v128 {
    2621    unsafe {
    2622        simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2623            a.as_i8x16(),
    2624            a.as_i8x16(),
    2625            [0, 1, 2, 3, 4, 5, 6, 7],
    2626        ))
    2627        .v128()
    2628    }
    2629}
    2630
    2631/// Converts high half of the smaller lane vector to a larger lane
    2632/// vector, sign extended.
    2633#[inline]
    2634#[cfg_attr(test, assert_instr(i16x8.extend_high_i8x16_s))]
    2635#[target_feature(enable = "simd128")]
    2636#[doc(alias("i16x8.extend_high_i8x16_s"))]
    2637#[stable(feature = "wasm_simd", since = "1.54.0")]
    2638pub fn i16x8_extend_high_i8x16(a: v128) -> v128 {
    2639    unsafe {
    2640        simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2641            a.as_i8x16(),
    2642            a.as_i8x16(),
    2643            [8, 9, 10, 11, 12, 13, 14, 15],
    2644        ))
    2645        .v128()
    2646    }
    2647}
    2648
    2649/// Converts low half of the smaller lane vector to a larger lane
    2650/// vector, zero extended.
    2651#[inline]
    2652#[cfg_attr(test, assert_instr(i16x8.extend_low_i8x16_u))]
    2653#[target_feature(enable = "simd128")]
    2654#[doc(alias("i16x8.extend_low_i8x16_u"))]
    2655#[stable(feature = "wasm_simd", since = "1.54.0")]
    2656pub fn i16x8_extend_low_u8x16(a: v128) -> v128 {
    2657    unsafe {
    2658        simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2659            a.as_u8x16(),
    2660            a.as_u8x16(),
    2661            [0, 1, 2, 3, 4, 5, 6, 7],
    2662        ))
    2663        .v128()
    2664    }
    2665}
    2666
    2667#[stable(feature = "wasm_simd", since = "1.54.0")]
    2668pub use i16x8_extend_low_u8x16 as u16x8_extend_low_u8x16;
    2669
    2670/// Converts high half of the smaller lane vector to a larger lane
    2671/// vector, zero extended.
    2672#[inline]
    2673#[cfg_attr(test, assert_instr(i16x8.extend_high_i8x16_u))]
    2674#[target_feature(enable = "simd128")]
    2675#[doc(alias("i16x8.extend_high_i8x16_u"))]
    2676#[stable(feature = "wasm_simd", since = "1.54.0")]
    2677pub fn i16x8_extend_high_u8x16(a: v128) -> v128 {
    2678    unsafe {
    2679        simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2680            a.as_u8x16(),
    2681            a.as_u8x16(),
    2682            [8, 9, 10, 11, 12, 13, 14, 15],
    2683        ))
    2684        .v128()
    2685    }
    2686}
    2687
    2688#[stable(feature = "wasm_simd", since = "1.54.0")]
    2689pub use i16x8_extend_high_u8x16 as u16x8_extend_high_u8x16;
    2690
    2691/// Shifts each lane to the left by the specified number of bits.
    2692///
    2693/// Only the low bits of the shift amount are used if the shift amount is
    2694/// greater than the lane width.
    2695#[inline]
    2696#[cfg_attr(test, assert_instr(i16x8.shl))]
    2697#[target_feature(enable = "simd128")]
    2698#[doc(alias("i16x8.shl"))]
    2699#[stable(feature = "wasm_simd", since = "1.54.0")]
    2700pub fn i16x8_shl(a: v128, amt: u32) -> v128 {
    2701    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    2702    // essentially the shift amount must be valid hence the mask.
    2703    unsafe { simd_shl(a.as_i16x8(), simd::i16x8::splat((amt & 0xf) as i16)).v128() }
    2704}
    2705
    2706#[stable(feature = "wasm_simd", since = "1.54.0")]
    2707pub use i16x8_shl as u16x8_shl;
    2708
    2709/// Shifts each lane to the right by the specified number of bits, sign
    2710/// extending.
    2711///
    2712/// Only the low bits of the shift amount are used if the shift amount is
    2713/// greater than the lane width.
    2714#[inline]
    2715#[cfg_attr(test, assert_instr(i16x8.shr_s))]
    2716#[target_feature(enable = "simd128")]
    2717#[doc(alias("i16x8.shr_s"))]
    2718#[stable(feature = "wasm_simd", since = "1.54.0")]
    2719pub fn i16x8_shr(a: v128, amt: u32) -> v128 {
    2720    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    2721    // essentially the shift amount must be valid hence the mask.
    2722    unsafe { simd_shr(a.as_i16x8(), simd::i16x8::splat((amt & 0xf) as i16)).v128() }
    2723}
    2724
    2725/// Shifts each lane to the right by the specified number of bits, shifting in
    2726/// zeros.
    2727///
    2728/// Only the low bits of the shift amount are used if the shift amount is
    2729/// greater than the lane width.
    2730#[inline]
    2731#[cfg_attr(test, assert_instr(i16x8.shr_u))]
    2732#[target_feature(enable = "simd128")]
    2733#[doc(alias("i16x8.shr_u"))]
    2734#[stable(feature = "wasm_simd", since = "1.54.0")]
    2735pub fn u16x8_shr(a: v128, amt: u32) -> v128 {
    2736    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    2737    // essentially the shift amount must be valid hence the mask.
    2738    unsafe { simd_shr(a.as_u16x8(), simd::u16x8::splat((amt & 0xf) as u16)).v128() }
    2739}
    2740
    2741/// Adds two 128-bit vectors as if they were two packed eight 16-bit integers.
    2742#[inline]
    2743#[cfg_attr(test, assert_instr(i16x8.add))]
    2744#[target_feature(enable = "simd128")]
    2745#[doc(alias("i16x8.add"))]
    2746#[stable(feature = "wasm_simd", since = "1.54.0")]
    2747pub fn i16x8_add(a: v128, b: v128) -> v128 {
    2748    unsafe { simd_add(a.as_i16x8(), b.as_i16x8()).v128() }
    2749}
    2750
    2751#[stable(feature = "wasm_simd", since = "1.54.0")]
    2752pub use i16x8_add as u16x8_add;
    2753
    2754/// Adds two 128-bit vectors as if they were two packed eight 16-bit signed
    2755/// integers, saturating on overflow to `i16::MAX`.
    2756#[inline]
    2757#[cfg_attr(test, assert_instr(i16x8.add_sat_s))]
    2758#[target_feature(enable = "simd128")]
    2759#[doc(alias("i16x8.add_sat_s"))]
    2760#[stable(feature = "wasm_simd", since = "1.54.0")]
    2761pub fn i16x8_add_sat(a: v128, b: v128) -> v128 {
    2762    unsafe { simd_saturating_add(a.as_i16x8(), b.as_i16x8()).v128() }
    2763}
    2764
    2765/// Adds two 128-bit vectors as if they were two packed eight 16-bit unsigned
    2766/// integers, saturating on overflow to `u16::MAX`.
    2767#[inline]
    2768#[cfg_attr(test, assert_instr(i16x8.add_sat_u))]
    2769#[target_feature(enable = "simd128")]
    2770#[doc(alias("i16x8.add_sat_u"))]
    2771#[stable(feature = "wasm_simd", since = "1.54.0")]
    2772pub fn u16x8_add_sat(a: v128, b: v128) -> v128 {
    2773    unsafe { simd_saturating_add(a.as_u16x8(), b.as_u16x8()).v128() }
    2774}
    2775
    2776/// Subtracts two 128-bit vectors as if they were two packed eight 16-bit integers.
    2777#[inline]
    2778#[cfg_attr(test, assert_instr(i16x8.sub))]
    2779#[target_feature(enable = "simd128")]
    2780#[doc(alias("i16x8.sub"))]
    2781#[stable(feature = "wasm_simd", since = "1.54.0")]
    2782pub fn i16x8_sub(a: v128, b: v128) -> v128 {
    2783    unsafe { simd_sub(a.as_i16x8(), b.as_i16x8()).v128() }
    2784}
    2785
    2786#[stable(feature = "wasm_simd", since = "1.54.0")]
    2787pub use i16x8_sub as u16x8_sub;
    2788
    2789/// Subtracts two 128-bit vectors as if they were two packed eight 16-bit
    2790/// signed integers, saturating on overflow to `i16::MIN`.
    2791#[inline]
    2792#[cfg_attr(test, assert_instr(i16x8.sub_sat_s))]
    2793#[target_feature(enable = "simd128")]
    2794#[doc(alias("i16x8.sub_sat_s"))]
    2795#[stable(feature = "wasm_simd", since = "1.54.0")]
    2796pub fn i16x8_sub_sat(a: v128, b: v128) -> v128 {
    2797    unsafe { simd_saturating_sub(a.as_i16x8(), b.as_i16x8()).v128() }
    2798}
    2799
    2800/// Subtracts two 128-bit vectors as if they were two packed eight 16-bit
    2801/// unsigned integers, saturating on overflow to 0.
    2802#[inline]
    2803#[cfg_attr(test, assert_instr(i16x8.sub_sat_u))]
    2804#[target_feature(enable = "simd128")]
    2805#[doc(alias("i16x8.sub_sat_u"))]
    2806#[stable(feature = "wasm_simd", since = "1.54.0")]
    2807pub fn u16x8_sub_sat(a: v128, b: v128) -> v128 {
    2808    unsafe { simd_saturating_sub(a.as_u16x8(), b.as_u16x8()).v128() }
    2809}
    2810
    2811/// Multiplies two 128-bit vectors as if they were two packed eight 16-bit
    2812/// signed integers.
    2813#[inline]
    2814#[cfg_attr(test, assert_instr(i16x8.mul))]
    2815#[target_feature(enable = "simd128")]
    2816#[doc(alias("i16x8.mul"))]
    2817#[stable(feature = "wasm_simd", since = "1.54.0")]
    2818pub fn i16x8_mul(a: v128, b: v128) -> v128 {
    2819    unsafe { simd_mul(a.as_i16x8(), b.as_i16x8()).v128() }
    2820}
    2821
    2822#[stable(feature = "wasm_simd", since = "1.54.0")]
    2823pub use i16x8_mul as u16x8_mul;
    2824
    2825/// Compares lane-wise signed integers, and returns the minimum of
    2826/// each pair.
    2827#[inline]
    2828#[cfg_attr(test, assert_instr(i16x8.min_s))]
    2829#[target_feature(enable = "simd128")]
    2830#[doc(alias("i16x8.min_s"))]
    2831#[stable(feature = "wasm_simd", since = "1.54.0")]
    2832pub fn i16x8_min(a: v128, b: v128) -> v128 {
    2833    let a = a.as_i16x8();
    2834    let b = b.as_i16x8();
    2835    unsafe { simd_select::<simd::i16x8, _>(simd_lt(a, b), a, b).v128() }
    2836}
    2837
    2838/// Compares lane-wise unsigned integers, and returns the minimum of
    2839/// each pair.
    2840#[inline]
    2841#[cfg_attr(test, assert_instr(i16x8.min_u))]
    2842#[target_feature(enable = "simd128")]
    2843#[doc(alias("i16x8.min_u"))]
    2844#[stable(feature = "wasm_simd", since = "1.54.0")]
    2845pub fn u16x8_min(a: v128, b: v128) -> v128 {
    2846    let a = a.as_u16x8();
    2847    let b = b.as_u16x8();
    2848    unsafe { simd_select::<simd::i16x8, _>(simd_lt(a, b), a, b).v128() }
    2849}
    2850
    2851/// Compares lane-wise signed integers, and returns the maximum of
    2852/// each pair.
    2853#[inline]
    2854#[cfg_attr(test, assert_instr(i16x8.max_s))]
    2855#[target_feature(enable = "simd128")]
    2856#[doc(alias("i16x8.max_s"))]
    2857#[stable(feature = "wasm_simd", since = "1.54.0")]
    2858pub fn i16x8_max(a: v128, b: v128) -> v128 {
    2859    let a = a.as_i16x8();
    2860    let b = b.as_i16x8();
    2861    unsafe { simd_select::<simd::i16x8, _>(simd_gt(a, b), a, b).v128() }
    2862}
    2863
    2864/// Compares lane-wise unsigned integers, and returns the maximum of
    2865/// each pair.
    2866#[inline]
    2867#[cfg_attr(test, assert_instr(i16x8.max_u))]
    2868#[target_feature(enable = "simd128")]
    2869#[doc(alias("i16x8.max_u"))]
    2870#[stable(feature = "wasm_simd", since = "1.54.0")]
    2871pub fn u16x8_max(a: v128, b: v128) -> v128 {
    2872    let a = a.as_u16x8();
    2873    let b = b.as_u16x8();
    2874    unsafe { simd_select::<simd::i16x8, _>(simd_gt(a, b), a, b).v128() }
    2875}
    2876
    2877/// Lane-wise rounding average.
    2878#[inline]
    2879#[cfg_attr(test, assert_instr(i16x8.avgr_u))]
    2880#[target_feature(enable = "simd128")]
    2881#[doc(alias("i16x8.avgr_u"))]
    2882#[stable(feature = "wasm_simd", since = "1.54.0")]
    2883pub fn u16x8_avgr(a: v128, b: v128) -> v128 {
    2884    unsafe { llvm_avgr_u_i16x8(a.as_i16x8(), b.as_i16x8()).v128() }
    2885}
    2886
    2887/// Lane-wise integer extended multiplication producing twice wider result than
    2888/// the inputs.
    2889///
    2890/// Equivalent of `i16x8_mul(i16x8_extend_low_i8x16(a), i16x8_extend_low_i8x16(b))`
    2891#[inline]
    2892#[cfg_attr(test, assert_instr(i16x8.extmul_low_i8x16_s))]
    2893#[target_feature(enable = "simd128")]
    2894#[doc(alias("i16x8.extmul_low_i8x16_s"))]
    2895#[stable(feature = "wasm_simd", since = "1.54.0")]
    2896pub fn i16x8_extmul_low_i8x16(a: v128, b: v128) -> v128 {
    2897    unsafe {
    2898        let lhs = simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2899            a.as_i8x16(),
    2900            a.as_i8x16(),
    2901            [0, 1, 2, 3, 4, 5, 6, 7],
    2902        ));
    2903        let rhs = simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2904            b.as_i8x16(),
    2905            b.as_i8x16(),
    2906            [0, 1, 2, 3, 4, 5, 6, 7],
    2907        ));
    2908        simd_mul(lhs, rhs).v128()
    2909    }
    2910}
    2911
    2912/// Lane-wise integer extended multiplication producing twice wider result than
    2913/// the inputs.
    2914///
    2915/// Equivalent of `i16x8_mul(i16x8_extend_high_i8x16(a), i16x8_extend_high_i8x16(b))`
    2916#[inline]
    2917#[cfg_attr(test, assert_instr(i16x8.extmul_high_i8x16_s))]
    2918#[target_feature(enable = "simd128")]
    2919#[doc(alias("i16x8.extmul_high_i8x16_s"))]
    2920#[stable(feature = "wasm_simd", since = "1.54.0")]
    2921pub fn i16x8_extmul_high_i8x16(a: v128, b: v128) -> v128 {
    2922    unsafe {
    2923        let lhs = simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2924            a.as_i8x16(),
    2925            a.as_i8x16(),
    2926            [8, 9, 10, 11, 12, 13, 14, 15],
    2927        ));
    2928        let rhs = simd_cast::<simd::i8x8, simd::i16x8>(simd_shuffle!(
    2929            b.as_i8x16(),
    2930            b.as_i8x16(),
    2931            [8, 9, 10, 11, 12, 13, 14, 15],
    2932        ));
    2933        simd_mul(lhs, rhs).v128()
    2934    }
    2935}
    2936
    2937/// Lane-wise integer extended multiplication producing twice wider result than
    2938/// the inputs.
    2939///
    2940/// Equivalent of `i16x8_mul(i16x8_extend_low_u8x16(a), i16x8_extend_low_u8x16(b))`
    2941#[inline]
    2942#[cfg_attr(test, assert_instr(i16x8.extmul_low_i8x16_u))]
    2943#[target_feature(enable = "simd128")]
    2944#[doc(alias("i16x8.extmul_low_i8x16_u"))]
    2945#[stable(feature = "wasm_simd", since = "1.54.0")]
    2946pub fn i16x8_extmul_low_u8x16(a: v128, b: v128) -> v128 {
    2947    unsafe {
    2948        let lhs = simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2949            a.as_u8x16(),
    2950            a.as_u8x16(),
    2951            [0, 1, 2, 3, 4, 5, 6, 7],
    2952        ));
    2953        let rhs = simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2954            b.as_u8x16(),
    2955            b.as_u8x16(),
    2956            [0, 1, 2, 3, 4, 5, 6, 7],
    2957        ));
    2958        simd_mul(lhs, rhs).v128()
    2959    }
    2960}
    2961
    2962#[stable(feature = "wasm_simd", since = "1.54.0")]
    2963pub use i16x8_extmul_low_u8x16 as u16x8_extmul_low_u8x16;
    2964
    2965/// Lane-wise integer extended multiplication producing twice wider result than
    2966/// the inputs.
    2967///
    2968/// Equivalent of `i16x8_mul(i16x8_extend_high_u8x16(a), i16x8_extend_high_u8x16(b))`
    2969#[inline]
    2970#[cfg_attr(test, assert_instr(i16x8.extmul_high_i8x16_u))]
    2971#[target_feature(enable = "simd128")]
    2972#[doc(alias("i16x8.extmul_high_i8x16_u"))]
    2973#[stable(feature = "wasm_simd", since = "1.54.0")]
    2974pub fn i16x8_extmul_high_u8x16(a: v128, b: v128) -> v128 {
    2975    unsafe {
    2976        let lhs = simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2977            a.as_u8x16(),
    2978            a.as_u8x16(),
    2979            [8, 9, 10, 11, 12, 13, 14, 15],
    2980        ));
    2981        let rhs = simd_cast::<simd::u8x8, simd::u16x8>(simd_shuffle!(
    2982            b.as_u8x16(),
    2983            b.as_u8x16(),
    2984            [8, 9, 10, 11, 12, 13, 14, 15],
    2985        ));
    2986        simd_mul(lhs, rhs).v128()
    2987    }
    2988}
    2989
    2990#[stable(feature = "wasm_simd", since = "1.54.0")]
    2991pub use i16x8_extmul_high_u8x16 as u16x8_extmul_high_u8x16;
    2992
    2993/// Integer extended pairwise addition producing extended results
    2994/// (twice wider results than the inputs).
    2995#[inline]
    2996#[cfg_attr(test, assert_instr(i32x4.extadd_pairwise_i16x8_s))]
    2997#[target_feature(enable = "simd128")]
    2998#[doc(alias("i32x4.extadd_pairwise_i16x8_s"))]
    2999#[stable(feature = "wasm_simd", since = "1.54.0")]
    3000pub fn i32x4_extadd_pairwise_i16x8(a: v128) -> v128 {
    3001    unsafe { llvm_i32x4_extadd_pairwise_i16x8_s(a.as_i16x8()).v128() }
    3002}
    3003
    3004/// Integer extended pairwise addition producing extended results
    3005/// (twice wider results than the inputs).
    3006#[inline]
    3007#[cfg_attr(test, assert_instr(i32x4.extadd_pairwise_i16x8_u))]
    3008#[doc(alias("i32x4.extadd_pairwise_i16x8_u"))]
    3009#[target_feature(enable = "simd128")]
    3010#[stable(feature = "wasm_simd", since = "1.54.0")]
    3011pub fn i32x4_extadd_pairwise_u16x8(a: v128) -> v128 {
    3012    unsafe { llvm_i32x4_extadd_pairwise_i16x8_u(a.as_i16x8()).v128() }
    3013}
    3014
    3015#[stable(feature = "wasm_simd", since = "1.54.0")]
    3016pub use i32x4_extadd_pairwise_u16x8 as u32x4_extadd_pairwise_u16x8;
    3017
    3018/// Lane-wise wrapping absolute value.
    3019#[inline]
    3020#[cfg_attr(test, assert_instr(i32x4.abs))]
    3021#[target_feature(enable = "simd128")]
    3022#[doc(alias("i32x4.abs"))]
    3023#[stable(feature = "wasm_simd", since = "1.54.0")]
    3024pub fn i32x4_abs(a: v128) -> v128 {
    3025    let a = a.as_i32x4();
    3026    let zero = simd::i32x4::ZERO;
    3027    unsafe {
    3028        simd_select::<simd::m32x4, simd::i32x4>(simd_lt(a, zero), simd_sub(zero, a), a).v128()
    3029    }
    3030}
    3031
    3032/// Negates a 128-bit vectors interpreted as four 32-bit signed integers
    3033#[inline]
    3034#[cfg_attr(test, assert_instr(i32x4.neg))]
    3035#[target_feature(enable = "simd128")]
    3036#[doc(alias("i32x4.neg"))]
    3037#[stable(feature = "wasm_simd", since = "1.54.0")]
    3038pub fn i32x4_neg(a: v128) -> v128 {
    3039    unsafe { simd_mul(a.as_i32x4(), simd::i32x4::splat(-1)).v128() }
    3040}
    3041
    3042/// Returns true if all lanes are non-zero, false otherwise.
    3043#[inline]
    3044#[cfg_attr(test, assert_instr(i32x4.all_true))]
    3045#[target_feature(enable = "simd128")]
    3046#[doc(alias("i32x4.all_true"))]
    3047#[stable(feature = "wasm_simd", since = "1.54.0")]
    3048pub fn i32x4_all_true(a: v128) -> bool {
    3049    unsafe { llvm_i32x4_all_true(a.as_i32x4()) != 0 }
    3050}
    3051
    3052#[stable(feature = "wasm_simd", since = "1.54.0")]
    3053pub use i32x4_all_true as u32x4_all_true;
    3054
    3055/// Extracts the high bit for each lane in `a` and produce a scalar mask with
    3056/// all bits concatenated.
    3057#[inline]
    3058#[cfg_attr(test, assert_instr(i32x4.bitmask))]
    3059#[target_feature(enable = "simd128")]
    3060#[doc(alias("i32x4.bitmask"))]
    3061#[stable(feature = "wasm_simd", since = "1.54.0")]
    3062pub fn i32x4_bitmask(a: v128) -> u8 {
    3063    unsafe { llvm_bitmask_i32x4(a.as_i32x4()) as u8 }
    3064}
    3065
    3066#[stable(feature = "wasm_simd", since = "1.54.0")]
    3067pub use i32x4_bitmask as u32x4_bitmask;
    3068
    3069/// Converts low half of the smaller lane vector to a larger lane
    3070/// vector, sign extended.
    3071#[inline]
    3072#[cfg_attr(test, assert_instr(i32x4.extend_low_i16x8_s))]
    3073#[target_feature(enable = "simd128")]
    3074#[doc(alias("i32x4.extend_low_i16x8_s"))]
    3075#[stable(feature = "wasm_simd", since = "1.54.0")]
    3076pub fn i32x4_extend_low_i16x8(a: v128) -> v128 {
    3077    unsafe {
    3078        simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3079            a.as_i16x8(),
    3080            a.as_i16x8(),
    3081            [0, 1, 2, 3]
    3082        ))
    3083        .v128()
    3084    }
    3085}
    3086
    3087/// Converts high half of the smaller lane vector to a larger lane
    3088/// vector, sign extended.
    3089#[inline]
    3090#[cfg_attr(test, assert_instr(i32x4.extend_high_i16x8_s))]
    3091#[target_feature(enable = "simd128")]
    3092#[doc(alias("i32x4.extend_high_i16x8_s"))]
    3093#[stable(feature = "wasm_simd", since = "1.54.0")]
    3094pub fn i32x4_extend_high_i16x8(a: v128) -> v128 {
    3095    unsafe {
    3096        simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3097            a.as_i16x8(),
    3098            a.as_i16x8(),
    3099            [4, 5, 6, 7]
    3100        ))
    3101        .v128()
    3102    }
    3103}
    3104
    3105/// Converts low half of the smaller lane vector to a larger lane
    3106/// vector, zero extended.
    3107#[inline]
    3108#[cfg_attr(test, assert_instr(i32x4.extend_low_i16x8_u))]
    3109#[target_feature(enable = "simd128")]
    3110#[doc(alias("i32x4.extend_low_i16x8_u"))]
    3111#[stable(feature = "wasm_simd", since = "1.54.0")]
    3112pub fn i32x4_extend_low_u16x8(a: v128) -> v128 {
    3113    unsafe {
    3114        simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3115            a.as_u16x8(),
    3116            a.as_u16x8(),
    3117            [0, 1, 2, 3]
    3118        ))
    3119        .v128()
    3120    }
    3121}
    3122
    3123#[stable(feature = "wasm_simd", since = "1.54.0")]
    3124pub use i32x4_extend_low_u16x8 as u32x4_extend_low_u16x8;
    3125
    3126/// Converts high half of the smaller lane vector to a larger lane
    3127/// vector, zero extended.
    3128#[inline]
    3129#[cfg_attr(test, assert_instr(i32x4.extend_high_i16x8_u))]
    3130#[target_feature(enable = "simd128")]
    3131#[doc(alias("i32x4.extend_high_i16x8_u"))]
    3132#[stable(feature = "wasm_simd", since = "1.54.0")]
    3133pub fn i32x4_extend_high_u16x8(a: v128) -> v128 {
    3134    unsafe {
    3135        simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3136            a.as_u16x8(),
    3137            a.as_u16x8(),
    3138            [4, 5, 6, 7]
    3139        ))
    3140        .v128()
    3141    }
    3142}
    3143
    3144#[stable(feature = "wasm_simd", since = "1.54.0")]
    3145pub use i32x4_extend_high_u16x8 as u32x4_extend_high_u16x8;
    3146
    3147/// Shifts each lane to the left by the specified number of bits.
    3148///
    3149/// Only the low bits of the shift amount are used if the shift amount is
    3150/// greater than the lane width.
    3151#[inline]
    3152#[cfg_attr(test, assert_instr(i32x4.shl))]
    3153#[target_feature(enable = "simd128")]
    3154#[doc(alias("i32x4.shl"))]
    3155#[stable(feature = "wasm_simd", since = "1.54.0")]
    3156pub fn i32x4_shl(a: v128, amt: u32) -> v128 {
    3157    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3158    // essentially the shift amount must be valid hence the mask.
    3159    unsafe { simd_shl(a.as_i32x4(), simd::i32x4::splat((amt & 0x1f) as i32)).v128() }
    3160}
    3161
    3162#[stable(feature = "wasm_simd", since = "1.54.0")]
    3163pub use i32x4_shl as u32x4_shl;
    3164
    3165/// Shifts each lane to the right by the specified number of bits, sign
    3166/// extending.
    3167///
    3168/// Only the low bits of the shift amount are used if the shift amount is
    3169/// greater than the lane width.
    3170#[inline]
    3171#[cfg_attr(test, assert_instr(i32x4.shr_s))]
    3172#[target_feature(enable = "simd128")]
    3173#[doc(alias("i32x4.shr_s"))]
    3174#[stable(feature = "wasm_simd", since = "1.54.0")]
    3175pub fn i32x4_shr(a: v128, amt: u32) -> v128 {
    3176    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3177    // essentially the shift amount must be valid hence the mask.
    3178    unsafe { simd_shr(a.as_i32x4(), simd::i32x4::splat((amt & 0x1f) as i32)).v128() }
    3179}
    3180
    3181/// Shifts each lane to the right by the specified number of bits, shifting in
    3182/// zeros.
    3183///
    3184/// Only the low bits of the shift amount are used if the shift amount is
    3185/// greater than the lane width.
    3186#[inline]
    3187#[cfg_attr(test, assert_instr(i32x4.shr_u))]
    3188#[target_feature(enable = "simd128")]
    3189#[doc(alias("i32x4.shr_u"))]
    3190#[stable(feature = "wasm_simd", since = "1.54.0")]
    3191pub fn u32x4_shr(a: v128, amt: u32) -> v128 {
    3192    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3193    // essentially the shift amount must be valid hence the mask.
    3194    unsafe { simd_shr(a.as_u32x4(), simd::u32x4::splat(amt & 0x1f)).v128() }
    3195}
    3196
    3197/// Adds two 128-bit vectors as if they were two packed four 32-bit integers.
    3198#[inline]
    3199#[cfg_attr(test, assert_instr(i32x4.add))]
    3200#[target_feature(enable = "simd128")]
    3201#[doc(alias("i32x4.add"))]
    3202#[stable(feature = "wasm_simd", since = "1.54.0")]
    3203pub fn i32x4_add(a: v128, b: v128) -> v128 {
    3204    unsafe { simd_add(a.as_i32x4(), b.as_i32x4()).v128() }
    3205}
    3206
    3207#[stable(feature = "wasm_simd", since = "1.54.0")]
    3208pub use i32x4_add as u32x4_add;
    3209
    3210/// Subtracts two 128-bit vectors as if they were two packed four 32-bit integers.
    3211#[inline]
    3212#[cfg_attr(test, assert_instr(i32x4.sub))]
    3213#[target_feature(enable = "simd128")]
    3214#[doc(alias("i32x4.sub"))]
    3215#[stable(feature = "wasm_simd", since = "1.54.0")]
    3216pub fn i32x4_sub(a: v128, b: v128) -> v128 {
    3217    unsafe { simd_sub(a.as_i32x4(), b.as_i32x4()).v128() }
    3218}
    3219
    3220#[stable(feature = "wasm_simd", since = "1.54.0")]
    3221pub use i32x4_sub as u32x4_sub;
    3222
    3223/// Multiplies two 128-bit vectors as if they were two packed four 32-bit
    3224/// signed integers.
    3225#[inline]
    3226#[cfg_attr(test, assert_instr(i32x4.mul))]
    3227#[target_feature(enable = "simd128")]
    3228#[doc(alias("i32x4.mul"))]
    3229#[stable(feature = "wasm_simd", since = "1.54.0")]
    3230pub fn i32x4_mul(a: v128, b: v128) -> v128 {
    3231    unsafe { simd_mul(a.as_i32x4(), b.as_i32x4()).v128() }
    3232}
    3233
    3234#[stable(feature = "wasm_simd", since = "1.54.0")]
    3235pub use i32x4_mul as u32x4_mul;
    3236
    3237/// Compares lane-wise signed integers, and returns the minimum of
    3238/// each pair.
    3239#[inline]
    3240#[cfg_attr(test, assert_instr(i32x4.min_s))]
    3241#[target_feature(enable = "simd128")]
    3242#[doc(alias("i32x4.min_s"))]
    3243#[stable(feature = "wasm_simd", since = "1.54.0")]
    3244pub fn i32x4_min(a: v128, b: v128) -> v128 {
    3245    let a = a.as_i32x4();
    3246    let b = b.as_i32x4();
    3247    unsafe { simd_select::<simd::i32x4, _>(simd_lt(a, b), a, b).v128() }
    3248}
    3249
    3250/// Compares lane-wise unsigned integers, and returns the minimum of
    3251/// each pair.
    3252#[inline]
    3253#[cfg_attr(test, assert_instr(i32x4.min_u))]
    3254#[target_feature(enable = "simd128")]
    3255#[doc(alias("i32x4.min_u"))]
    3256#[stable(feature = "wasm_simd", since = "1.54.0")]
    3257pub fn u32x4_min(a: v128, b: v128) -> v128 {
    3258    let a = a.as_u32x4();
    3259    let b = b.as_u32x4();
    3260    unsafe { simd_select::<simd::i32x4, _>(simd_lt(a, b), a, b).v128() }
    3261}
    3262
    3263/// Compares lane-wise signed integers, and returns the maximum of
    3264/// each pair.
    3265#[inline]
    3266#[cfg_attr(test, assert_instr(i32x4.max_s))]
    3267#[target_feature(enable = "simd128")]
    3268#[doc(alias("i32x4.max_s"))]
    3269#[stable(feature = "wasm_simd", since = "1.54.0")]
    3270pub fn i32x4_max(a: v128, b: v128) -> v128 {
    3271    let a = a.as_i32x4();
    3272    let b = b.as_i32x4();
    3273    unsafe { simd_select::<simd::i32x4, _>(simd_gt(a, b), a, b).v128() }
    3274}
    3275
    3276/// Compares lane-wise unsigned integers, and returns the maximum of
    3277/// each pair.
    3278#[inline]
    3279#[cfg_attr(test, assert_instr(i32x4.max_u))]
    3280#[target_feature(enable = "simd128")]
    3281#[doc(alias("i32x4.max_u"))]
    3282#[stable(feature = "wasm_simd", since = "1.54.0")]
    3283pub fn u32x4_max(a: v128, b: v128) -> v128 {
    3284    let a = a.as_u32x4();
    3285    let b = b.as_u32x4();
    3286    unsafe { simd_select::<simd::i32x4, _>(simd_gt(a, b), a, b).v128() }
    3287}
    3288
    3289/// Lane-wise multiply signed 16-bit integers in the two input vectors and add
    3290/// adjacent pairs of the full 32-bit results.
    3291#[inline]
    3292#[cfg_attr(test, assert_instr(i32x4.dot_i16x8_s))]
    3293#[target_feature(enable = "simd128")]
    3294#[doc(alias("i32x4.dot_i16x8_s"))]
    3295#[stable(feature = "wasm_simd", since = "1.54.0")]
    3296pub fn i32x4_dot_i16x8(a: v128, b: v128) -> v128 {
    3297    unsafe { llvm_i32x4_dot_i16x8_s(a.as_i16x8(), b.as_i16x8()).v128() }
    3298}
    3299
    3300/// Lane-wise integer extended multiplication producing twice wider result than
    3301/// the inputs.
    3302///
    3303/// Equivalent of `i32x4_mul(i32x4_extend_low_i16x8_s(a), i32x4_extend_low_i16x8_s(b))`
    3304#[inline]
    3305#[cfg_attr(test, assert_instr(i32x4.extmul_low_i16x8_s))]
    3306#[target_feature(enable = "simd128")]
    3307#[doc(alias("i32x4.extmul_low_i16x8_s"))]
    3308#[stable(feature = "wasm_simd", since = "1.54.0")]
    3309pub fn i32x4_extmul_low_i16x8(a: v128, b: v128) -> v128 {
    3310    unsafe {
    3311        let lhs = simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3312            a.as_i16x8(),
    3313            a.as_i16x8(),
    3314            [0, 1, 2, 3]
    3315        ));
    3316        let rhs = simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3317            b.as_i16x8(),
    3318            b.as_i16x8(),
    3319            [0, 1, 2, 3]
    3320        ));
    3321        simd_mul(lhs, rhs).v128()
    3322    }
    3323}
    3324
    3325/// Lane-wise integer extended multiplication producing twice wider result than
    3326/// the inputs.
    3327///
    3328/// Equivalent of `i32x4_mul(i32x4_extend_high_i16x8_s(a), i32x4_extend_high_i16x8_s(b))`
    3329#[inline]
    3330#[cfg_attr(test, assert_instr(i32x4.extmul_high_i16x8_s))]
    3331#[target_feature(enable = "simd128")]
    3332#[doc(alias("i32x4.extmul_high_i16x8_s"))]
    3333#[stable(feature = "wasm_simd", since = "1.54.0")]
    3334pub fn i32x4_extmul_high_i16x8(a: v128, b: v128) -> v128 {
    3335    unsafe {
    3336        let lhs = simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3337            a.as_i16x8(),
    3338            a.as_i16x8(),
    3339            [4, 5, 6, 7]
    3340        ));
    3341        let rhs = simd_cast::<simd::i16x4, simd::i32x4>(simd_shuffle!(
    3342            b.as_i16x8(),
    3343            b.as_i16x8(),
    3344            [4, 5, 6, 7]
    3345        ));
    3346        simd_mul(lhs, rhs).v128()
    3347    }
    3348}
    3349
    3350/// Lane-wise integer extended multiplication producing twice wider result than
    3351/// the inputs.
    3352///
    3353/// Equivalent of `i32x4_mul(i32x4_extend_low_u16x8(a), i32x4_extend_low_u16x8(b))`
    3354#[inline]
    3355#[cfg_attr(test, assert_instr(i32x4.extmul_low_i16x8_u))]
    3356#[target_feature(enable = "simd128")]
    3357#[doc(alias("i32x4.extmul_low_i16x8_u"))]
    3358#[stable(feature = "wasm_simd", since = "1.54.0")]
    3359pub fn i32x4_extmul_low_u16x8(a: v128, b: v128) -> v128 {
    3360    unsafe {
    3361        let lhs = simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3362            a.as_u16x8(),
    3363            a.as_u16x8(),
    3364            [0, 1, 2, 3]
    3365        ));
    3366        let rhs = simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3367            b.as_u16x8(),
    3368            b.as_u16x8(),
    3369            [0, 1, 2, 3]
    3370        ));
    3371        simd_mul(lhs, rhs).v128()
    3372    }
    3373}
    3374
    3375#[stable(feature = "wasm_simd", since = "1.54.0")]
    3376pub use i32x4_extmul_low_u16x8 as u32x4_extmul_low_u16x8;
    3377
    3378/// Lane-wise integer extended multiplication producing twice wider result than
    3379/// the inputs.
    3380///
    3381/// Equivalent of `i32x4_mul(i32x4_extend_high_u16x8(a), i32x4_extend_high_u16x8(b))`
    3382#[inline]
    3383#[cfg_attr(test, assert_instr(i32x4.extmul_high_i16x8_u))]
    3384#[target_feature(enable = "simd128")]
    3385#[doc(alias("i32x4.extmul_high_i16x8_u"))]
    3386#[stable(feature = "wasm_simd", since = "1.54.0")]
    3387pub fn i32x4_extmul_high_u16x8(a: v128, b: v128) -> v128 {
    3388    unsafe {
    3389        let lhs = simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3390            a.as_u16x8(),
    3391            a.as_u16x8(),
    3392            [4, 5, 6, 7]
    3393        ));
    3394        let rhs = simd_cast::<simd::u16x4, simd::u32x4>(simd_shuffle!(
    3395            b.as_u16x8(),
    3396            b.as_u16x8(),
    3397            [4, 5, 6, 7]
    3398        ));
    3399        simd_mul(lhs, rhs).v128()
    3400    }
    3401}
    3402
    3403#[stable(feature = "wasm_simd", since = "1.54.0")]
    3404pub use i32x4_extmul_high_u16x8 as u32x4_extmul_high_u16x8;
    3405
    3406/// Lane-wise wrapping absolute value.
    3407#[inline]
    3408#[cfg_attr(test, assert_instr(i64x2.abs))]
    3409#[target_feature(enable = "simd128")]
    3410#[doc(alias("i64x2.abs"))]
    3411#[stable(feature = "wasm_simd", since = "1.54.0")]
    3412pub fn i64x2_abs(a: v128) -> v128 {
    3413    let a = a.as_i64x2();
    3414    let zero = simd::i64x2::ZERO;
    3415    unsafe {
    3416        simd_select::<simd::m64x2, simd::i64x2>(simd_lt(a, zero), simd_sub(zero, a), a).v128()
    3417    }
    3418}
    3419
    3420/// Negates a 128-bit vectors interpreted as two 64-bit signed integers
    3421#[inline]
    3422#[cfg_attr(test, assert_instr(i64x2.neg))]
    3423#[target_feature(enable = "simd128")]
    3424#[doc(alias("i64x2.neg"))]
    3425#[stable(feature = "wasm_simd", since = "1.54.0")]
    3426pub fn i64x2_neg(a: v128) -> v128 {
    3427    unsafe { simd_mul(a.as_i64x2(), simd::i64x2::splat(-1)).v128() }
    3428}
    3429
    3430/// Returns true if all lanes are non-zero, false otherwise.
    3431#[inline]
    3432#[cfg_attr(test, assert_instr(i64x2.all_true))]
    3433#[target_feature(enable = "simd128")]
    3434#[doc(alias("i64x2.all_true"))]
    3435#[stable(feature = "wasm_simd", since = "1.54.0")]
    3436pub fn i64x2_all_true(a: v128) -> bool {
    3437    unsafe { llvm_i64x2_all_true(a.as_i64x2()) != 0 }
    3438}
    3439
    3440#[stable(feature = "wasm_simd", since = "1.54.0")]
    3441pub use i64x2_all_true as u64x2_all_true;
    3442
    3443/// Extracts the high bit for each lane in `a` and produce a scalar mask with
    3444/// all bits concatenated.
    3445#[inline]
    3446#[cfg_attr(test, assert_instr(i64x2.bitmask))]
    3447#[target_feature(enable = "simd128")]
    3448#[doc(alias("i64x2.bitmask"))]
    3449#[stable(feature = "wasm_simd", since = "1.54.0")]
    3450pub fn i64x2_bitmask(a: v128) -> u8 {
    3451    unsafe { llvm_bitmask_i64x2(a.as_i64x2()) as u8 }
    3452}
    3453
    3454#[stable(feature = "wasm_simd", since = "1.54.0")]
    3455pub use i64x2_bitmask as u64x2_bitmask;
    3456
    3457/// Converts low half of the smaller lane vector to a larger lane
    3458/// vector, sign extended.
    3459#[inline]
    3460#[cfg_attr(test, assert_instr(i64x2.extend_low_i32x4_s))]
    3461#[target_feature(enable = "simd128")]
    3462#[doc(alias("i64x2.extend_low_i32x4_s"))]
    3463#[stable(feature = "wasm_simd", since = "1.54.0")]
    3464pub fn i64x2_extend_low_i32x4(a: v128) -> v128 {
    3465    unsafe {
    3466        simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(a.as_i32x4(), a.as_i32x4(), [0, 1]))
    3467            .v128()
    3468    }
    3469}
    3470
    3471/// Converts high half of the smaller lane vector to a larger lane
    3472/// vector, sign extended.
    3473#[inline]
    3474#[cfg_attr(test, assert_instr(i64x2.extend_high_i32x4_s))]
    3475#[target_feature(enable = "simd128")]
    3476#[doc(alias("i64x2.extend_high_i32x4_s"))]
    3477#[stable(feature = "wasm_simd", since = "1.54.0")]
    3478pub fn i64x2_extend_high_i32x4(a: v128) -> v128 {
    3479    unsafe {
    3480        simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(a.as_i32x4(), a.as_i32x4(), [2, 3]))
    3481            .v128()
    3482    }
    3483}
    3484
    3485/// Converts low half of the smaller lane vector to a larger lane
    3486/// vector, zero extended.
    3487#[inline]
    3488#[cfg_attr(test, assert_instr(i64x2.extend_low_i32x4_u))]
    3489#[target_feature(enable = "simd128")]
    3490#[doc(alias("i64x2.extend_low_i32x4_u"))]
    3491#[stable(feature = "wasm_simd", since = "1.54.0")]
    3492pub fn i64x2_extend_low_u32x4(a: v128) -> v128 {
    3493    unsafe {
    3494        simd_cast::<simd::u32x2, simd::i64x2>(simd_shuffle!(a.as_u32x4(), a.as_u32x4(), [0, 1]))
    3495            .v128()
    3496    }
    3497}
    3498
    3499#[stable(feature = "wasm_simd", since = "1.54.0")]
    3500pub use i64x2_extend_low_u32x4 as u64x2_extend_low_u32x4;
    3501
    3502/// Converts high half of the smaller lane vector to a larger lane
    3503/// vector, zero extended.
    3504#[inline]
    3505#[cfg_attr(test, assert_instr(i64x2.extend_high_i32x4_u))]
    3506#[target_feature(enable = "simd128")]
    3507#[doc(alias("i64x2.extend_high_i32x4_u"))]
    3508#[stable(feature = "wasm_simd", since = "1.54.0")]
    3509pub fn i64x2_extend_high_u32x4(a: v128) -> v128 {
    3510    unsafe {
    3511        simd_cast::<simd::u32x2, simd::i64x2>(simd_shuffle!(a.as_u32x4(), a.as_u32x4(), [2, 3]))
    3512            .v128()
    3513    }
    3514}
    3515
    3516#[stable(feature = "wasm_simd", since = "1.54.0")]
    3517pub use i64x2_extend_high_u32x4 as u64x2_extend_high_u32x4;
    3518
    3519/// Shifts each lane to the left by the specified number of bits.
    3520///
    3521/// Only the low bits of the shift amount are used if the shift amount is
    3522/// greater than the lane width.
    3523#[inline]
    3524#[cfg_attr(test, assert_instr(i64x2.shl))]
    3525#[target_feature(enable = "simd128")]
    3526#[doc(alias("i64x2.shl"))]
    3527#[stable(feature = "wasm_simd", since = "1.54.0")]
    3528pub fn i64x2_shl(a: v128, amt: u32) -> v128 {
    3529    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3530    // essentially the shift amount must be valid hence the mask.
    3531    unsafe { simd_shl(a.as_i64x2(), simd::i64x2::splat((amt & 0x3f) as i64)).v128() }
    3532}
    3533
    3534#[stable(feature = "wasm_simd", since = "1.54.0")]
    3535pub use i64x2_shl as u64x2_shl;
    3536
    3537/// Shifts each lane to the right by the specified number of bits, sign
    3538/// extending.
    3539///
    3540/// Only the low bits of the shift amount are used if the shift amount is
    3541/// greater than the lane width.
    3542#[inline]
    3543#[cfg_attr(test, assert_instr(i64x2.shr_s))]
    3544#[target_feature(enable = "simd128")]
    3545#[doc(alias("i64x2.shr_s"))]
    3546#[stable(feature = "wasm_simd", since = "1.54.0")]
    3547pub fn i64x2_shr(a: v128, amt: u32) -> v128 {
    3548    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3549    // essentially the shift amount must be valid hence the mask.
    3550    unsafe { simd_shr(a.as_i64x2(), simd::i64x2::splat((amt & 0x3f) as i64)).v128() }
    3551}
    3552
    3553/// Shifts each lane to the right by the specified number of bits, shifting in
    3554/// zeros.
    3555///
    3556/// Only the low bits of the shift amount are used if the shift amount is
    3557/// greater than the lane width.
    3558#[inline]
    3559#[cfg_attr(test, assert_instr(i64x2.shr_u))]
    3560#[target_feature(enable = "simd128")]
    3561#[doc(alias("i64x2.shr_u"))]
    3562#[stable(feature = "wasm_simd", since = "1.54.0")]
    3563pub fn u64x2_shr(a: v128, amt: u32) -> v128 {
    3564    // SAFETY: see i8x16_shl for more documentation why this is unsafe,
    3565    // essentially the shift amount must be valid hence the mask.
    3566    unsafe { simd_shr(a.as_u64x2(), simd::u64x2::splat((amt & 0x3f) as u64)).v128() }
    3567}
    3568
    3569/// Adds two 128-bit vectors as if they were two packed two 64-bit integers.
    3570#[inline]
    3571#[cfg_attr(test, assert_instr(i64x2.add))]
    3572#[target_feature(enable = "simd128")]
    3573#[doc(alias("i64x2.add"))]
    3574#[stable(feature = "wasm_simd", since = "1.54.0")]
    3575pub fn i64x2_add(a: v128, b: v128) -> v128 {
    3576    unsafe { simd_add(a.as_i64x2(), b.as_i64x2()).v128() }
    3577}
    3578
    3579#[stable(feature = "wasm_simd", since = "1.54.0")]
    3580pub use i64x2_add as u64x2_add;
    3581
    3582/// Subtracts two 128-bit vectors as if they were two packed two 64-bit integers.
    3583#[inline]
    3584#[cfg_attr(test, assert_instr(i64x2.sub))]
    3585#[target_feature(enable = "simd128")]
    3586#[doc(alias("i64x2.sub"))]
    3587#[stable(feature = "wasm_simd", since = "1.54.0")]
    3588pub fn i64x2_sub(a: v128, b: v128) -> v128 {
    3589    unsafe { simd_sub(a.as_i64x2(), b.as_i64x2()).v128() }
    3590}
    3591
    3592#[stable(feature = "wasm_simd", since = "1.54.0")]
    3593pub use i64x2_sub as u64x2_sub;
    3594
    3595/// Multiplies two 128-bit vectors as if they were two packed two 64-bit integers.
    3596#[inline]
    3597#[cfg_attr(test, assert_instr(i64x2.mul))]
    3598#[target_feature(enable = "simd128")]
    3599#[doc(alias("i64x2.mul"))]
    3600#[stable(feature = "wasm_simd", since = "1.54.0")]
    3601pub fn i64x2_mul(a: v128, b: v128) -> v128 {
    3602    unsafe { simd_mul(a.as_i64x2(), b.as_i64x2()).v128() }
    3603}
    3604
    3605#[stable(feature = "wasm_simd", since = "1.54.0")]
    3606pub use i64x2_mul as u64x2_mul;
    3607
    3608/// Lane-wise integer extended multiplication producing twice wider result than
    3609/// the inputs.
    3610///
    3611/// Equivalent of `i64x2_mul(i64x2_extend_low_i32x4_s(a), i64x2_extend_low_i32x4_s(b))`
    3612#[inline]
    3613#[cfg_attr(test, assert_instr(i64x2.extmul_low_i32x4_s))]
    3614#[target_feature(enable = "simd128")]
    3615#[doc(alias("i64x2.extmul_low_i32x4_s"))]
    3616#[stable(feature = "wasm_simd", since = "1.54.0")]
    3617pub fn i64x2_extmul_low_i32x4(a: v128, b: v128) -> v128 {
    3618    unsafe {
    3619        let lhs = simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(
    3620            a.as_i32x4(),
    3621            a.as_i32x4(),
    3622            [0, 1]
    3623        ));
    3624        let rhs = simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(
    3625            b.as_i32x4(),
    3626            b.as_i32x4(),
    3627            [0, 1]
    3628        ));
    3629        simd_mul(lhs, rhs).v128()
    3630    }
    3631}
    3632
    3633/// Lane-wise integer extended multiplication producing twice wider result than
    3634/// the inputs.
    3635///
    3636/// Equivalent of `i64x2_mul(i64x2_extend_high_i32x4_s(a), i64x2_extend_high_i32x4_s(b))`
    3637#[inline]
    3638#[cfg_attr(test, assert_instr(i64x2.extmul_high_i32x4_s))]
    3639#[target_feature(enable = "simd128")]
    3640#[doc(alias("i64x2.extmul_high_i32x4_s"))]
    3641#[stable(feature = "wasm_simd", since = "1.54.0")]
    3642pub fn i64x2_extmul_high_i32x4(a: v128, b: v128) -> v128 {
    3643    unsafe {
    3644        let lhs = simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(
    3645            a.as_i32x4(),
    3646            a.as_i32x4(),
    3647            [2, 3]
    3648        ));
    3649        let rhs = simd_cast::<simd::i32x2, simd::i64x2>(simd_shuffle!(
    3650            b.as_i32x4(),
    3651            b.as_i32x4(),
    3652            [2, 3]
    3653        ));
    3654        simd_mul(lhs, rhs).v128()
    3655    }
    3656}
    3657
    3658/// Lane-wise integer extended multiplication producing twice wider result than
    3659/// the inputs.
    3660///
    3661/// Equivalent of `i64x2_mul(i64x2_extend_low_i32x4_u(a), i64x2_extend_low_i32x4_u(b))`
    3662#[inline]
    3663#[cfg_attr(test, assert_instr(i64x2.extmul_low_i32x4_u))]
    3664#[target_feature(enable = "simd128")]
    3665#[doc(alias("i64x2.extmul_low_i32x4_u"))]
    3666#[stable(feature = "wasm_simd", since = "1.54.0")]
    3667pub fn i64x2_extmul_low_u32x4(a: v128, b: v128) -> v128 {
    3668    unsafe {
    3669        let lhs = simd_cast::<simd::u32x2, simd::u64x2>(simd_shuffle!(
    3670            a.as_u32x4(),
    3671            a.as_u32x4(),
    3672            [0, 1]
    3673        ));
    3674        let rhs = simd_cast::<simd::u32x2, simd::u64x2>(simd_shuffle!(
    3675            b.as_u32x4(),
    3676            b.as_u32x4(),
    3677            [0, 1]
    3678        ));
    3679        simd_mul(lhs, rhs).v128()
    3680    }
    3681}
    3682
    3683#[stable(feature = "wasm_simd", since = "1.54.0")]
    3684pub use i64x2_extmul_low_u32x4 as u64x2_extmul_low_u32x4;
    3685
    3686/// Lane-wise integer extended multiplication producing twice wider result than
    3687/// the inputs.
    3688///
    3689/// Equivalent of `i64x2_mul(i64x2_extend_high_i32x4_u(a), i64x2_extend_high_i32x4_u(b))`
    3690#[inline]
    3691#[cfg_attr(test, assert_instr(i64x2.extmul_high_i32x4_u))]
    3692#[target_feature(enable = "simd128")]
    3693#[doc(alias("i64x2.extmul_high_i32x4_u"))]
    3694#[stable(feature = "wasm_simd", since = "1.54.0")]
    3695pub fn i64x2_extmul_high_u32x4(a: v128, b: v128) -> v128 {
    3696    unsafe {
    3697        let lhs = simd_cast::<simd::u32x2, simd::u64x2>(simd_shuffle!(
    3698            a.as_u32x4(),
    3699            a.as_u32x4(),
    3700            [2, 3]
    3701        ));
    3702        let rhs = simd_cast::<simd::u32x2, simd::u64x2>(simd_shuffle!(
    3703            b.as_u32x4(),
    3704            b.as_u32x4(),
    3705            [2, 3]
    3706        ));
    3707        simd_mul(lhs, rhs).v128()
    3708    }
    3709}
    3710
    3711#[stable(feature = "wasm_simd", since = "1.54.0")]
    3712pub use i64x2_extmul_high_u32x4 as u64x2_extmul_high_u32x4;
    3713
    3714/// Lane-wise rounding to the nearest integral value not smaller than the input.
    3715#[inline]
    3716#[cfg_attr(test, assert_instr(f32x4.ceil))]
    3717#[target_feature(enable = "simd128")]
    3718#[doc(alias("f32x4.ceil"))]
    3719#[stable(feature = "wasm_simd", since = "1.54.0")]
    3720pub fn f32x4_ceil(a: v128) -> v128 {
    3721    unsafe { simd_ceil(a.as_f32x4()).v128() }
    3722}
    3723
    3724/// Lane-wise rounding to the nearest integral value not greater than the input.
    3725#[inline]
    3726#[cfg_attr(test, assert_instr(f32x4.floor))]
    3727#[target_feature(enable = "simd128")]
    3728#[doc(alias("f32x4.floor"))]
    3729#[stable(feature = "wasm_simd", since = "1.54.0")]
    3730pub fn f32x4_floor(a: v128) -> v128 {
    3731    unsafe { simd_floor(a.as_f32x4()).v128() }
    3732}
    3733
    3734/// Lane-wise rounding to the nearest integral value with the magnitude not
    3735/// larger than the input.
    3736#[inline]
    3737#[cfg_attr(test, assert_instr(f32x4.trunc))]
    3738#[target_feature(enable = "simd128")]
    3739#[doc(alias("f32x4.trunc"))]
    3740#[stable(feature = "wasm_simd", since = "1.54.0")]
    3741pub fn f32x4_trunc(a: v128) -> v128 {
    3742    unsafe { simd_trunc(a.as_f32x4()).v128() }
    3743}
    3744
    3745/// Lane-wise rounding to the nearest integral value; if two values are equally
    3746/// near, rounds to the even one.
    3747#[inline]
    3748#[cfg_attr(test, assert_instr(f32x4.nearest))]
    3749#[target_feature(enable = "simd128")]
    3750#[doc(alias("f32x4.nearest"))]
    3751#[stable(feature = "wasm_simd", since = "1.54.0")]
    3752pub fn f32x4_nearest(a: v128) -> v128 {
    3753    unsafe { llvm_f32x4_nearest(a.as_f32x4()).v128() }
    3754}
    3755
    3756/// Calculates the absolute value of each lane of a 128-bit vector interpreted
    3757/// as four 32-bit floating point numbers.
    3758#[inline]
    3759#[cfg_attr(test, assert_instr(f32x4.abs))]
    3760#[target_feature(enable = "simd128")]
    3761#[doc(alias("f32x4.abs"))]
    3762#[stable(feature = "wasm_simd", since = "1.54.0")]
    3763pub fn f32x4_abs(a: v128) -> v128 {
    3764    unsafe { simd_fabs(a.as_f32x4()).v128() }
    3765}
    3766
    3767/// Negates each lane of a 128-bit vector interpreted as four 32-bit floating
    3768/// point numbers.
    3769#[inline]
    3770#[cfg_attr(test, assert_instr(f32x4.neg))]
    3771#[target_feature(enable = "simd128")]
    3772#[doc(alias("f32x4.neg"))]
    3773#[stable(feature = "wasm_simd", since = "1.54.0")]
    3774pub fn f32x4_neg(a: v128) -> v128 {
    3775    unsafe { simd_neg(a.as_f32x4()).v128() }
    3776}
    3777
    3778/// Calculates the square root of each lane of a 128-bit vector interpreted as
    3779/// four 32-bit floating point numbers.
    3780#[inline]
    3781#[cfg_attr(test, assert_instr(f32x4.sqrt))]
    3782#[target_feature(enable = "simd128")]
    3783#[doc(alias("f32x4.sqrt"))]
    3784#[stable(feature = "wasm_simd", since = "1.54.0")]
    3785pub fn f32x4_sqrt(a: v128) -> v128 {
    3786    unsafe { simd_fsqrt(a.as_f32x4()).v128() }
    3787}
    3788
    3789/// Lane-wise addition of two 128-bit vectors interpreted as four 32-bit
    3790/// floating point numbers.
    3791#[inline]
    3792#[cfg_attr(test, assert_instr(f32x4.add))]
    3793#[target_feature(enable = "simd128")]
    3794#[doc(alias("f32x4.add"))]
    3795#[stable(feature = "wasm_simd", since = "1.54.0")]
    3796pub fn f32x4_add(a: v128, b: v128) -> v128 {
    3797    unsafe { simd_add(a.as_f32x4(), b.as_f32x4()).v128() }
    3798}
    3799
    3800/// Lane-wise subtraction of two 128-bit vectors interpreted as four 32-bit
    3801/// floating point numbers.
    3802#[inline]
    3803#[cfg_attr(test, assert_instr(f32x4.sub))]
    3804#[target_feature(enable = "simd128")]
    3805#[doc(alias("f32x4.sub"))]
    3806#[stable(feature = "wasm_simd", since = "1.54.0")]
    3807pub fn f32x4_sub(a: v128, b: v128) -> v128 {
    3808    unsafe { simd_sub(a.as_f32x4(), b.as_f32x4()).v128() }
    3809}
    3810
    3811/// Lane-wise multiplication of two 128-bit vectors interpreted as four 32-bit
    3812/// floating point numbers.
    3813#[inline]
    3814#[cfg_attr(test, assert_instr(f32x4.mul))]
    3815#[target_feature(enable = "simd128")]
    3816#[doc(alias("f32x4.mul"))]
    3817#[stable(feature = "wasm_simd", since = "1.54.0")]
    3818pub fn f32x4_mul(a: v128, b: v128) -> v128 {
    3819    unsafe { simd_mul(a.as_f32x4(), b.as_f32x4()).v128() }
    3820}
    3821
    3822/// Lane-wise division of two 128-bit vectors interpreted as four 32-bit
    3823/// floating point numbers.
    3824#[inline]
    3825#[cfg_attr(test, assert_instr(f32x4.div))]
    3826#[target_feature(enable = "simd128")]
    3827#[doc(alias("f32x4.div"))]
    3828#[stable(feature = "wasm_simd", since = "1.54.0")]
    3829pub fn f32x4_div(a: v128, b: v128) -> v128 {
    3830    unsafe { simd_div(a.as_f32x4(), b.as_f32x4()).v128() }
    3831}
    3832
    3833/// Calculates the lane-wise minimum of two 128-bit vectors interpreted
    3834/// as four 32-bit floating point numbers.
    3835#[inline]
    3836#[cfg_attr(test, assert_instr(f32x4.min))]
    3837#[target_feature(enable = "simd128")]
    3838#[doc(alias("f32x4.min"))]
    3839#[stable(feature = "wasm_simd", since = "1.54.0")]
    3840pub fn f32x4_min(a: v128, b: v128) -> v128 {
    3841    unsafe { llvm_f32x4_min(a.as_f32x4(), b.as_f32x4()).v128() }
    3842}
    3843
    3844/// Calculates the lane-wise minimum of two 128-bit vectors interpreted
    3845/// as four 32-bit floating point numbers.
    3846#[inline]
    3847#[cfg_attr(test, assert_instr(f32x4.max))]
    3848#[target_feature(enable = "simd128")]
    3849#[doc(alias("f32x4.max"))]
    3850#[stable(feature = "wasm_simd", since = "1.54.0")]
    3851pub fn f32x4_max(a: v128, b: v128) -> v128 {
    3852    unsafe { llvm_f32x4_max(a.as_f32x4(), b.as_f32x4()).v128() }
    3853}
    3854
    3855/// Lane-wise minimum value, defined as `b < a ? b : a`
    3856#[inline]
    3857#[cfg_attr(test, assert_instr(f32x4.pmin))]
    3858#[target_feature(enable = "simd128")]
    3859#[doc(alias("f32x4.pmin"))]
    3860#[stable(feature = "wasm_simd", since = "1.54.0")]
    3861pub fn f32x4_pmin(a: v128, b: v128) -> v128 {
    3862    unsafe {
    3863        simd_select::<simd::m32x4, simd::f32x4>(
    3864            simd_lt(b.as_f32x4(), a.as_f32x4()),
    3865            b.as_f32x4(),
    3866            a.as_f32x4(),
    3867        )
    3868        .v128()
    3869    }
    3870}
    3871
    3872/// Lane-wise maximum value, defined as `a < b ? b : a`
    3873#[inline]
    3874#[cfg_attr(test, assert_instr(f32x4.pmax))]
    3875#[target_feature(enable = "simd128")]
    3876#[doc(alias("f32x4.pmax"))]
    3877#[stable(feature = "wasm_simd", since = "1.54.0")]
    3878pub fn f32x4_pmax(a: v128, b: v128) -> v128 {
    3879    unsafe {
    3880        simd_select::<simd::m32x4, simd::f32x4>(
    3881            simd_lt(a.as_f32x4(), b.as_f32x4()),
    3882            b.as_f32x4(),
    3883            a.as_f32x4(),
    3884        )
    3885        .v128()
    3886    }
    3887}
    3888
    3889/// Lane-wise rounding to the nearest integral value not smaller than the input.
    3890#[inline]
    3891#[cfg_attr(test, assert_instr(f64x2.ceil))]
    3892#[target_feature(enable = "simd128")]
    3893#[doc(alias("f64x2.ceil"))]
    3894#[stable(feature = "wasm_simd", since = "1.54.0")]
    3895pub fn f64x2_ceil(a: v128) -> v128 {
    3896    unsafe { simd_ceil(a.as_f64x2()).v128() }
    3897}
    3898
    3899/// Lane-wise rounding to the nearest integral value not greater than the input.
    3900#[inline]
    3901#[cfg_attr(test, assert_instr(f64x2.floor))]
    3902#[target_feature(enable = "simd128")]
    3903#[doc(alias("f64x2.floor"))]
    3904#[stable(feature = "wasm_simd", since = "1.54.0")]
    3905pub fn f64x2_floor(a: v128) -> v128 {
    3906    unsafe { simd_floor(a.as_f64x2()).v128() }
    3907}
    3908
    3909/// Lane-wise rounding to the nearest integral value with the magnitude not
    3910/// larger than the input.
    3911#[inline]
    3912#[cfg_attr(test, assert_instr(f64x2.trunc))]
    3913#[target_feature(enable = "simd128")]
    3914#[doc(alias("f64x2.trunc"))]
    3915#[stable(feature = "wasm_simd", since = "1.54.0")]
    3916pub fn f64x2_trunc(a: v128) -> v128 {
    3917    unsafe { simd_trunc(a.as_f64x2()).v128() }
    3918}
    3919
    3920/// Lane-wise rounding to the nearest integral value; if two values are equally
    3921/// near, rounds to the even one.
    3922#[inline]
    3923#[cfg_attr(test, assert_instr(f64x2.nearest))]
    3924#[target_feature(enable = "simd128")]
    3925#[doc(alias("f64x2.nearest"))]
    3926#[stable(feature = "wasm_simd", since = "1.54.0")]
    3927pub fn f64x2_nearest(a: v128) -> v128 {
    3928    unsafe { llvm_f64x2_nearest(a.as_f64x2()).v128() }
    3929}
    3930
    3931/// Calculates the absolute value of each lane of a 128-bit vector interpreted
    3932/// as two 64-bit floating point numbers.
    3933#[inline]
    3934#[cfg_attr(test, assert_instr(f64x2.abs))]
    3935#[target_feature(enable = "simd128")]
    3936#[doc(alias("f64x2.abs"))]
    3937#[stable(feature = "wasm_simd", since = "1.54.0")]
    3938pub fn f64x2_abs(a: v128) -> v128 {
    3939    unsafe { simd_fabs(a.as_f64x2()).v128() }
    3940}
    3941
    3942/// Negates each lane of a 128-bit vector interpreted as two 64-bit floating
    3943/// point numbers.
    3944#[inline]
    3945#[cfg_attr(test, assert_instr(f64x2.neg))]
    3946#[target_feature(enable = "simd128")]
    3947#[doc(alias("f64x2.neg"))]
    3948#[stable(feature = "wasm_simd", since = "1.54.0")]
    3949pub fn f64x2_neg(a: v128) -> v128 {
    3950    unsafe { simd_neg(a.as_f64x2()).v128() }
    3951}
    3952
    3953/// Calculates the square root of each lane of a 128-bit vector interpreted as
    3954/// two 64-bit floating point numbers.
    3955#[inline]
    3956#[cfg_attr(test, assert_instr(f64x2.sqrt))]
    3957#[target_feature(enable = "simd128")]
    3958#[doc(alias("f64x2.sqrt"))]
    3959#[stable(feature = "wasm_simd", since = "1.54.0")]
    3960pub fn f64x2_sqrt(a: v128) -> v128 {
    3961    unsafe { simd_fsqrt(a.as_f64x2()).v128() }
    3962}
    3963
    3964/// Lane-wise add of two 128-bit vectors interpreted as two 64-bit
    3965/// floating point numbers.
    3966#[inline]
    3967#[cfg_attr(test, assert_instr(f64x2.add))]
    3968#[target_feature(enable = "simd128")]
    3969#[doc(alias("f64x2.add"))]
    3970#[stable(feature = "wasm_simd", since = "1.54.0")]
    3971pub fn f64x2_add(a: v128, b: v128) -> v128 {
    3972    unsafe { simd_add(a.as_f64x2(), b.as_f64x2()).v128() }
    3973}
    3974
    3975/// Lane-wise subtract of two 128-bit vectors interpreted as two 64-bit
    3976/// floating point numbers.
    3977#[inline]
    3978#[cfg_attr(test, assert_instr(f64x2.sub))]
    3979#[target_feature(enable = "simd128")]
    3980#[doc(alias("f64x2.sub"))]
    3981#[stable(feature = "wasm_simd", since = "1.54.0")]
    3982pub fn f64x2_sub(a: v128, b: v128) -> v128 {
    3983    unsafe { simd_sub(a.as_f64x2(), b.as_f64x2()).v128() }
    3984}
    3985
    3986/// Lane-wise multiply of two 128-bit vectors interpreted as two 64-bit
    3987/// floating point numbers.
    3988#[inline]
    3989#[cfg_attr(test, assert_instr(f64x2.mul))]
    3990#[target_feature(enable = "simd128")]
    3991#[doc(alias("f64x2.mul"))]
    3992#[stable(feature = "wasm_simd", since = "1.54.0")]
    3993pub fn f64x2_mul(a: v128, b: v128) -> v128 {
    3994    unsafe { simd_mul(a.as_f64x2(), b.as_f64x2()).v128() }
    3995}
    3996
    3997/// Lane-wise divide of two 128-bit vectors interpreted as two 64-bit
    3998/// floating point numbers.
    3999#[inline]
    4000#[cfg_attr(test, assert_instr(f64x2.div))]
    4001#[target_feature(enable = "simd128")]
    4002#[doc(alias("f64x2.div"))]
    4003#[stable(feature = "wasm_simd", since = "1.54.0")]
    4004pub fn f64x2_div(a: v128, b: v128) -> v128 {
    4005    unsafe { simd_div(a.as_f64x2(), b.as_f64x2()).v128() }
    4006}
    4007
    4008/// Calculates the lane-wise minimum of two 128-bit vectors interpreted
    4009/// as two 64-bit floating point numbers.
    4010#[inline]
    4011#[cfg_attr(test, assert_instr(f64x2.min))]
    4012#[target_feature(enable = "simd128")]
    4013#[doc(alias("f64x2.min"))]
    4014#[stable(feature = "wasm_simd", since = "1.54.0")]
    4015pub fn f64x2_min(a: v128, b: v128) -> v128 {
    4016    unsafe { llvm_f64x2_min(a.as_f64x2(), b.as_f64x2()).v128() }
    4017}
    4018
    4019/// Calculates the lane-wise maximum of two 128-bit vectors interpreted
    4020/// as two 64-bit floating point numbers.
    4021#[inline]
    4022#[cfg_attr(test, assert_instr(f64x2.max))]
    4023#[target_feature(enable = "simd128")]
    4024#[doc(alias("f64x2.max"))]
    4025#[stable(feature = "wasm_simd", since = "1.54.0")]
    4026pub fn f64x2_max(a: v128, b: v128) -> v128 {
    4027    unsafe { llvm_f64x2_max(a.as_f64x2(), b.as_f64x2()).v128() }
    4028}
    4029
    4030/// Lane-wise minimum value, defined as `b < a ? b : a`
    4031#[inline]
    4032#[cfg_attr(test, assert_instr(f64x2.pmin))]
    4033#[target_feature(enable = "simd128")]
    4034#[doc(alias("f64x2.pmin"))]
    4035#[stable(feature = "wasm_simd", since = "1.54.0")]
    4036pub fn f64x2_pmin(a: v128, b: v128) -> v128 {
    4037    unsafe {
    4038        simd_select::<simd::m64x2, simd::f64x2>(
    4039            simd_lt(b.as_f64x2(), a.as_f64x2()),
    4040            b.as_f64x2(),
    4041            a.as_f64x2(),
    4042        )
    4043        .v128()
    4044    }
    4045}
    4046
    4047/// Lane-wise maximum value, defined as `a < b ? b : a`
    4048#[inline]
    4049#[cfg_attr(test, assert_instr(f64x2.pmax))]
    4050#[target_feature(enable = "simd128")]
    4051#[doc(alias("f64x2.pmax"))]
    4052#[stable(feature = "wasm_simd", since = "1.54.0")]
    4053pub fn f64x2_pmax(a: v128, b: v128) -> v128 {
    4054    unsafe {
    4055        simd_select::<simd::m64x2, simd::f64x2>(
    4056            simd_lt(a.as_f64x2(), b.as_f64x2()),
    4057            b.as_f64x2(),
    4058            a.as_f64x2(),
    4059        )
    4060        .v128()
    4061    }
    4062}
    4063
    4064/// Converts a 128-bit vector interpreted as four 32-bit floating point numbers
    4065/// into a 128-bit vector of four 32-bit signed integers.
    4066///
    4067/// NaN is converted to 0 and if it's out of bounds it becomes the nearest
    4068/// representable intger.
    4069#[inline]
    4070#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f32x4_s))]
    4071#[target_feature(enable = "simd128")]
    4072#[doc(alias("i32x4.trunc_sat_f32x4_s"))]
    4073#[stable(feature = "wasm_simd", since = "1.54.0")]
    4074pub fn i32x4_trunc_sat_f32x4(a: v128) -> v128 {
    4075    unsafe { simd_as::<simd::f32x4, simd::i32x4>(a.as_f32x4()).v128() }
    4076}
    4077
    4078/// Converts a 128-bit vector interpreted as four 32-bit floating point numbers
    4079/// into a 128-bit vector of four 32-bit unsigned integers.
    4080///
    4081/// NaN is converted to 0 and if it's out of bounds it becomes the nearest
    4082/// representable intger.
    4083#[inline]
    4084#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f32x4_u))]
    4085#[target_feature(enable = "simd128")]
    4086#[doc(alias("i32x4.trunc_sat_f32x4_u"))]
    4087#[stable(feature = "wasm_simd", since = "1.54.0")]
    4088pub fn u32x4_trunc_sat_f32x4(a: v128) -> v128 {
    4089    unsafe { simd_as::<simd::f32x4, simd::u32x4>(a.as_f32x4()).v128() }
    4090}
    4091
    4092/// Converts a 128-bit vector interpreted as four 32-bit signed integers into a
    4093/// 128-bit vector of four 32-bit floating point numbers.
    4094#[inline]
    4095#[cfg_attr(test, assert_instr(f32x4.convert_i32x4_s))]
    4096#[target_feature(enable = "simd128")]
    4097#[doc(alias("f32x4.convert_i32x4_s"))]
    4098#[stable(feature = "wasm_simd", since = "1.54.0")]
    4099pub fn f32x4_convert_i32x4(a: v128) -> v128 {
    4100    unsafe { simd_cast::<_, simd::f32x4>(a.as_i32x4()).v128() }
    4101}
    4102
    4103/// Converts a 128-bit vector interpreted as four 32-bit unsigned integers into a
    4104/// 128-bit vector of four 32-bit floating point numbers.
    4105#[inline]
    4106#[cfg_attr(test, assert_instr(f32x4.convert_i32x4_u))]
    4107#[target_feature(enable = "simd128")]
    4108#[doc(alias("f32x4.convert_i32x4_u"))]
    4109#[stable(feature = "wasm_simd", since = "1.54.0")]
    4110pub fn f32x4_convert_u32x4(a: v128) -> v128 {
    4111    unsafe { simd_cast::<_, simd::f32x4>(a.as_u32x4()).v128() }
    4112}
    4113
    4114/// Saturating conversion of the two double-precision floating point lanes to
    4115/// two lower integer lanes using the IEEE `convertToIntegerTowardZero`
    4116/// function.
    4117///
    4118/// The two higher lanes of the result are initialized to zero. If any input
    4119/// lane is a NaN, the resulting lane is 0. If the rounded integer value of a
    4120/// lane is outside the range of the destination type, the result is saturated
    4121/// to the nearest representable integer value.
    4122#[inline]
    4123#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f64x2_s_zero))]
    4124#[target_feature(enable = "simd128")]
    4125#[doc(alias("i32x4.trunc_sat_f64x2_s_zero"))]
    4126#[stable(feature = "wasm_simd", since = "1.54.0")]
    4127pub fn i32x4_trunc_sat_f64x2_zero(a: v128) -> v128 {
    4128    let ret: simd::i32x4 = unsafe {
    4129        simd_shuffle!(
    4130            simd_as::<simd::f64x2, simd::i32x2>(a.as_f64x2()),
    4131            simd::i32x2::ZERO,
    4132            [0, 1, 2, 3],
    4133        )
    4134    };
    4135    ret.v128()
    4136}
    4137
    4138/// Saturating conversion of the two double-precision floating point lanes to
    4139/// two lower integer lanes using the IEEE `convertToIntegerTowardZero`
    4140/// function.
    4141///
    4142/// The two higher lanes of the result are initialized to zero. If any input
    4143/// lane is a NaN, the resulting lane is 0. If the rounded integer value of a
    4144/// lane is outside the range of the destination type, the result is saturated
    4145/// to the nearest representable integer value.
    4146#[inline]
    4147#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f64x2_u_zero))]
    4148#[target_feature(enable = "simd128")]
    4149#[doc(alias("i32x4.trunc_sat_f64x2_u_zero"))]
    4150#[stable(feature = "wasm_simd", since = "1.54.0")]
    4151pub fn u32x4_trunc_sat_f64x2_zero(a: v128) -> v128 {
    4152    let ret: simd::u32x4 = unsafe {
    4153        simd_shuffle!(
    4154            simd_as::<simd::f64x2, simd::u32x2>(a.as_f64x2()),
    4155            simd::u32x2::ZERO,
    4156            [0, 1, 2, 3],
    4157        )
    4158    };
    4159    ret.v128()
    4160}
    4161
    4162/// Lane-wise conversion from integer to floating point.
    4163#[inline]
    4164#[cfg_attr(test, assert_instr(f64x2.convert_low_i32x4_s))]
    4165#[target_feature(enable = "simd128")]
    4166#[doc(alias("f64x2.convert_low_i32x4_s"))]
    4167#[stable(feature = "wasm_simd", since = "1.54.0")]
    4168pub fn f64x2_convert_low_i32x4(a: v128) -> v128 {
    4169    unsafe {
    4170        simd_cast::<simd::i32x2, simd::f64x2>(simd_shuffle!(a.as_i32x4(), a.as_i32x4(), [0, 1],))
    4171            .v128()
    4172    }
    4173}
    4174
    4175/// Lane-wise conversion from integer to floating point.
    4176#[inline]
    4177#[cfg_attr(test, assert_instr(f64x2.convert_low_i32x4_u))]
    4178#[target_feature(enable = "simd128")]
    4179#[doc(alias("f64x2.convert_low_i32x4_u"))]
    4180#[stable(feature = "wasm_simd", since = "1.54.0")]
    4181pub fn f64x2_convert_low_u32x4(a: v128) -> v128 {
    4182    unsafe {
    4183        simd_cast::<simd::u32x2, simd::f64x2>(simd_shuffle!(a.as_u32x4(), a.as_u32x4(), [0, 1],))
    4184            .v128()
    4185    }
    4186}
    4187
    4188/// Conversion of the two double-precision floating point lanes to two lower
    4189/// single-precision lanes of the result. The two higher lanes of the result are
    4190/// initialized to zero. If the conversion result is not representable as a
    4191/// single-precision floating point number, it is rounded to the nearest-even
    4192/// representable number.
    4193#[inline]
    4194#[cfg_attr(test, assert_instr(f32x4.demote_f64x2_zero))]
    4195#[target_feature(enable = "simd128")]
    4196#[doc(alias("f32x4.demote_f64x2_zero"))]
    4197#[stable(feature = "wasm_simd", since = "1.54.0")]
    4198pub fn f32x4_demote_f64x2_zero(a: v128) -> v128 {
    4199    unsafe {
    4200        simd_cast::<simd::f64x4, simd::f32x4>(simd_shuffle!(
    4201            a.as_f64x2(),
    4202            simd::f64x2::ZERO,
    4203            [0, 1, 2, 3]
    4204        ))
    4205        .v128()
    4206    }
    4207}
    4208
    4209/// Conversion of the two lower single-precision floating point lanes to the two
    4210/// double-precision lanes of the result.
    4211#[inline]
    4212#[cfg_attr(test, assert_instr(f64x2.promote_low_f32x4))]
    4213#[target_feature(enable = "simd128")]
    4214#[doc(alias("f32x4.promote_low_f32x4"))]
    4215#[stable(feature = "wasm_simd", since = "1.54.0")]
    4216pub fn f64x2_promote_low_f32x4(a: v128) -> v128 {
    4217    unsafe {
    4218        simd_cast::<simd::f32x2, simd::f64x2>(simd_shuffle!(a.as_f32x4(), a.as_f32x4(), [0, 1]))
    4219            .v128()
    4220    }
    4221}
    4222
    4223#[cfg(test)]
    4224mod tests {
    4225    use super::*;
    4226    use core::ops::{Add, Div, Mul, Neg, Sub};
    4227
    4228    use std::fmt::Debug;
    4229    use std::mem::transmute;
    4230    use std::num::Wrapping;
    4231    use std::prelude::v1::*;
    4232
    4233    const _C1: v128 = i8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    4234    const _C2: v128 = u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    4235    const _C3: v128 = i16x8(0, 1, 2, 3, 4, 5, 6, 7);
    4236    const _C4: v128 = u16x8(0, 1, 2, 3, 4, 5, 6, 7);
    4237    const _C5: v128 = i32x4(0, 1, 2, 3);
    4238    const _C6: v128 = u32x4(0, 1, 2, 3);
    4239    const _C7: v128 = i64x2(0, 1);
    4240    const _C8: v128 = u64x2(0, 1);
    4241    const _C9: v128 = f32x4(0.0, 1.0, 2.0, 3.0);
    4242    const _C10: v128 = f64x2(0.0, 1.0);
    4243
    4244    fn compare_bytes(a: v128, b: v128) {
    4245        let a: [u8; 16] = unsafe { transmute(a) };
    4246        let b: [u8; 16] = unsafe { transmute(b) };
    4247        assert_eq!(a, b);
    4248    }
    4249
    4250    #[test]
    4251    fn test_load() {
    4252        unsafe {
    4253            let arr: [i32; 4] = [0, 1, 2, 3];
    4254            let vec = v128_load(arr.as_ptr() as *const v128);
    4255            compare_bytes(vec, i32x4(0, 1, 2, 3));
    4256        }
    4257    }
    4258
    4259    #[test]
    4260    fn test_load_extend() {
    4261        unsafe {
    4262            let arr: [i8; 8] = [-3, -2, -1, 0, 1, 2, 3, 4];
    4263            let vec = i16x8_load_extend_i8x8(arr.as_ptr());
    4264            compare_bytes(vec, i16x8(-3, -2, -1, 0, 1, 2, 3, 4));
    4265            let vec = i16x8_load_extend_u8x8(arr.as_ptr() as *const u8);
    4266            compare_bytes(vec, i16x8(253, 254, 255, 0, 1, 2, 3, 4));
    4267
    4268            let arr: [i16; 4] = [-1, 0, 1, 2];
    4269            let vec = i32x4_load_extend_i16x4(arr.as_ptr());
    4270            compare_bytes(vec, i32x4(-1, 0, 1, 2));
    4271            let vec = i32x4_load_extend_u16x4(arr.as_ptr() as *const u16);
    4272            compare_bytes(vec, i32x4(65535, 0, 1, 2));
    4273
    4274            let arr: [i32; 2] = [-1, 1];
    4275            let vec = i64x2_load_extend_i32x2(arr.as_ptr());
    4276            compare_bytes(vec, i64x2(-1, 1));
    4277            let vec = i64x2_load_extend_u32x2(arr.as_ptr() as *const u32);
    4278            compare_bytes(vec, i64x2(u32::max_value().into(), 1));
    4279        }
    4280    }
    4281
    4282    #[test]
    4283    fn test_load_splat() {
    4284        unsafe {
    4285            compare_bytes(v128_load8_splat(&8), i8x16_splat(8));
    4286            compare_bytes(v128_load16_splat(&9), i16x8_splat(9));
    4287            compare_bytes(v128_load32_splat(&10), i32x4_splat(10));
    4288            compare_bytes(v128_load64_splat(&11), i64x2_splat(11));
    4289        }
    4290    }
    4291
    4292    #[test]
    4293    fn test_load_zero() {
    4294        unsafe {
    4295            compare_bytes(v128_load32_zero(&10), i32x4(10, 0, 0, 0));
    4296            compare_bytes(v128_load64_zero(&11), i64x2(11, 0));
    4297        }
    4298    }
    4299
    4300    #[test]
    4301    fn test_store() {
    4302        unsafe {
    4303            let mut spot = i8x16_splat(0);
    4304            v128_store(&mut spot, i8x16_splat(1));
    4305            compare_bytes(spot, i8x16_splat(1));
    4306        }
    4307    }
    4308
    4309    #[test]
    4310    fn test_load_lane() {
    4311        unsafe {
    4312            let zero = i8x16_splat(0);
    4313            compare_bytes(
    4314                v128_load8_lane::<2>(zero, &1),
    4315                i8x16_replace_lane::<2>(zero, 1),
    4316            );
    4317
    4318            compare_bytes(
    4319                v128_load16_lane::<2>(zero, &1),
    4320                i16x8_replace_lane::<2>(zero, 1),
    4321            );
    4322
    4323            compare_bytes(
    4324                v128_load32_lane::<2>(zero, &1),
    4325                i32x4_replace_lane::<2>(zero, 1),
    4326            );
    4327
    4328            compare_bytes(
    4329                v128_load64_lane::<1>(zero, &1),
    4330                i64x2_replace_lane::<1>(zero, 1),
    4331            );
    4332        }
    4333    }
    4334
    4335    #[test]
    4336    fn test_store_lane() {
    4337        unsafe {
    4338            let mut spot = 0;
    4339            let zero = i8x16_splat(0);
    4340            v128_store8_lane::<5>(i8x16_replace_lane::<5>(zero, 7), &mut spot);
    4341            assert_eq!(spot, 7);
    4342
    4343            let mut spot = 0;
    4344            v128_store16_lane::<5>(i16x8_replace_lane::<5>(zero, 7), &mut spot);
    4345            assert_eq!(spot, 7);
    4346
    4347            let mut spot = 0;
    4348            v128_store32_lane::<3>(i32x4_replace_lane::<3>(zero, 7), &mut spot);
    4349            assert_eq!(spot, 7);
    4350
    4351            let mut spot = 0;
    4352            v128_store64_lane::<0>(i64x2_replace_lane::<0>(zero, 7), &mut spot);
    4353            assert_eq!(spot, 7);
    4354        }
    4355    }
    4356
    4357    #[test]
    4358    fn test_i8x16() {
    4359        const A: v128 = super::i8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    4360        compare_bytes(A, A);
    4361
    4362        const _: v128 = i16x8(0, 1, 2, 3, 4, 5, 6, 7);
    4363        const _: v128 = i32x4(0, 1, 2, 3);
    4364        const _: v128 = i64x2(0, 1);
    4365        const _: v128 = f32x4(0., 1., 2., 3.);
    4366        const _: v128 = f64x2(0., 1.);
    4367
    4368        let bytes: [i16; 8] = unsafe { mem::transmute(i16x8(-1, -2, -3, -4, -5, -6, -7, -8)) };
    4369        assert_eq!(bytes, [-1, -2, -3, -4, -5, -6, -7, -8]);
    4370        let bytes: [i8; 16] = unsafe {
    4371            mem::transmute(i8x16(
    4372                -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16,
    4373            ))
    4374        };
    4375        assert_eq!(
    4376            bytes,
    4377            [
    4378                -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16
    4379            ]
    4380        );
    4381    }
    4382
    4383    #[test]
    4384    fn test_shuffle() {
    4385        let vec_a = i8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    4386        let vec_b = i8x16(
    4387            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    4388        );
    4389
    4390        let vec_r = i8x16_shuffle::<0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30>(
    4391            vec_a, vec_b,
    4392        );
    4393        let vec_e = i8x16(0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
    4394        compare_bytes(vec_r, vec_e);
    4395
    4396        let vec_a = i16x8(0, 1, 2, 3, 4, 5, 6, 7);
    4397        let vec_b = i16x8(8, 9, 10, 11, 12, 13, 14, 15);
    4398        let vec_r = i16x8_shuffle::<0, 8, 2, 10, 4, 12, 6, 14>(vec_a, vec_b);
    4399        let vec_e = i16x8(0, 8, 2, 10, 4, 12, 6, 14);
    4400        compare_bytes(vec_r, vec_e);
    4401
    4402        let vec_a = i32x4(0, 1, 2, 3);
    4403        let vec_b = i32x4(4, 5, 6, 7);
    4404        let vec_r = i32x4_shuffle::<0, 4, 2, 6>(vec_a, vec_b);
    4405        let vec_e = i32x4(0, 4, 2, 6);
    4406        compare_bytes(vec_r, vec_e);
    4407
    4408        let vec_a = i64x2(0, 1);
    4409        let vec_b = i64x2(2, 3);
    4410        let vec_r = i64x2_shuffle::<0, 2>(vec_a, vec_b);
    4411        let vec_e = i64x2(0, 2);
    4412        compare_bytes(vec_r, vec_e);
    4413    }
    4414
    4415    // tests extract and replace lanes
    4416    macro_rules! test_extract {
    4417        (
    4418            name: $test_id:ident,
    4419            extract: $extract:ident,
    4420            replace: $replace:ident,
    4421            elem: $elem:ty,
    4422            count: $count:expr,
    4423            indices: [$($idx:expr),*],
    4424        ) => {
    4425            #[test]
    4426            fn $test_id() {
    4427                unsafe {
    4428                    let arr: [$elem; $count] = [123 as $elem; $count];
    4429                    let vec: v128 = transmute(arr);
    4430                    $(
    4431                        assert_eq!($extract::<$idx>(vec), 123 as $elem);
    4432                    )*
    4433
    4434                    // create a vector from array and check that the indices contain
    4435                    // the same values as in the array:
    4436                    let arr: [$elem; $count] = [$($idx as $elem),*];
    4437                    let vec: v128 = transmute(arr);
    4438                    $(
    4439                        assert_eq!($extract::<$idx>(vec), $idx as $elem);
    4440
    4441                        let tmp = $replace::<$idx>(vec, 124 as $elem);
    4442                        assert_eq!($extract::<$idx>(tmp), 124 as $elem);
    4443                    )*
    4444                }
    4445            }
    4446        }
    4447    }
    4448
    4449    test_extract! {
    4450        name: test_i8x16_extract_replace,
    4451        extract: i8x16_extract_lane,
    4452        replace: i8x16_replace_lane,
    4453        elem: i8,
    4454        count: 16,
    4455        indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    4456    }
    4457    test_extract! {
    4458        name: test_i16x8_extract_replace,
    4459        extract: i16x8_extract_lane,
    4460        replace: i16x8_replace_lane,
    4461        elem: i16,
    4462        count: 8,
    4463        indices: [0, 1, 2, 3, 4, 5, 6, 7],
    4464    }
    4465    test_extract! {
    4466        name: test_i32x4_extract_replace,
    4467        extract: i32x4_extract_lane,
    4468        replace: i32x4_replace_lane,
    4469        elem: i32,
    4470        count: 4,
    4471        indices: [0, 1, 2, 3],
    4472    }
    4473    test_extract! {
    4474        name: test_i64x2_extract_replace,
    4475        extract: i64x2_extract_lane,
    4476        replace: i64x2_replace_lane,
    4477        elem: i64,
    4478        count: 2,
    4479        indices: [0, 1],
    4480    }
    4481    test_extract! {
    4482        name: test_f32x4_extract_replace,
    4483        extract: f32x4_extract_lane,
    4484        replace: f32x4_replace_lane,
    4485        elem: f32,
    4486        count: 4,
    4487        indices: [0, 1, 2, 3],
    4488    }
    4489    test_extract! {
    4490        name: test_f64x2_extract_replace,
    4491        extract: f64x2_extract_lane,
    4492        replace: f64x2_replace_lane,
    4493        elem: f64,
    4494        count: 2,
    4495        indices: [0, 1],
    4496    }
    4497
    4498    #[test]
    4499    #[rustfmt::skip]
    4500    fn test_swizzle() {
    4501        compare_bytes(
    4502            i8x16_swizzle(
    4503                i32x4(1, 2, 3, 4),
    4504                i8x16(
    4505                    32, 31, 30, 29,
    4506                    0, 1, 2, 3,
    4507                    12, 13, 14, 15,
    4508                    0, 4, 8, 12),
    4509            ),
    4510            i32x4(0, 1, 4, 0x04030201),
    4511        );
    4512    }
    4513
    4514    macro_rules! test_splat {
    4515        ($test_id:ident: $val:expr => $($vals:expr),*) => {
    4516            #[test]
    4517            fn $test_id() {
    4518                let a = super::$test_id($val);
    4519                let b = u8x16($($vals as u8),*);
    4520                compare_bytes(a, b);
    4521            }
    4522        }
    4523    }
    4524
    4525    mod splats {
    4526        use super::*;
    4527        test_splat!(i8x16_splat: 42 => 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42);
    4528        test_splat!(i16x8_splat: 42 => 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0);
    4529        test_splat!(i32x4_splat: 42 => 42, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0);
    4530        test_splat!(i64x2_splat: 42 => 42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0);
    4531        test_splat!(f32x4_splat: 42. => 0, 0, 40, 66, 0, 0, 40, 66, 0, 0, 40, 66, 0, 0, 40, 66);
    4532        test_splat!(f64x2_splat: 42. => 0, 0, 0, 0, 0, 0, 69, 64, 0, 0, 0, 0, 0, 0, 69, 64);
    4533    }
    4534
    4535    #[test]
    4536    fn test_bitmasks() {
    4537        let zero = i8x16_splat(0);
    4538        let ones = i8x16_splat(!0);
    4539
    4540        assert_eq!(i8x16_bitmask(zero), 0);
    4541        assert_eq!(i8x16_bitmask(ones), 0xffff);
    4542        assert_eq!(i8x16_bitmask(i8x16_splat(i8::MAX)), 0);
    4543        assert_eq!(i8x16_bitmask(i8x16_splat(i8::MIN)), 0xffff);
    4544        assert_eq!(i8x16_bitmask(i8x16_replace_lane::<1>(zero, -1)), 0b10);
    4545
    4546        assert_eq!(i16x8_bitmask(zero), 0);
    4547        assert_eq!(i16x8_bitmask(ones), 0xff);
    4548        assert_eq!(i16x8_bitmask(i16x8_splat(i16::MAX)), 0);
    4549        assert_eq!(i16x8_bitmask(i16x8_splat(i16::MIN)), 0xff);
    4550        assert_eq!(i16x8_bitmask(i16x8_replace_lane::<1>(zero, -1)), 0b10);
    4551
    4552        assert_eq!(i32x4_bitmask(zero), 0);
    4553        assert_eq!(i32x4_bitmask(ones), 0b1111);
    4554        assert_eq!(i32x4_bitmask(i32x4_splat(i32::MAX)), 0);
    4555        assert_eq!(i32x4_bitmask(i32x4_splat(i32::MIN)), 0b1111);
    4556        assert_eq!(i32x4_bitmask(i32x4_replace_lane::<1>(zero, -1)), 0b10);
    4557
    4558        assert_eq!(i64x2_bitmask(zero), 0);
    4559        assert_eq!(i64x2_bitmask(ones), 0b11);
    4560        assert_eq!(i64x2_bitmask(i64x2_splat(i64::MAX)), 0);
    4561        assert_eq!(i64x2_bitmask(i64x2_splat(i64::MIN)), 0b11);
    4562        assert_eq!(i64x2_bitmask(i64x2_replace_lane::<1>(zero, -1)), 0b10);
    4563    }
    4564
    4565    #[test]
    4566    fn test_narrow() {
    4567        let zero = i8x16_splat(0);
    4568        let ones = i8x16_splat(!0);
    4569
    4570        compare_bytes(i8x16_narrow_i16x8(zero, zero), zero);
    4571        compare_bytes(u8x16_narrow_i16x8(zero, zero), zero);
    4572        compare_bytes(i8x16_narrow_i16x8(ones, ones), ones);
    4573        compare_bytes(u8x16_narrow_i16x8(ones, ones), zero);
    4574
    4575        compare_bytes(
    4576            i8x16_narrow_i16x8(
    4577                i16x8(
    4578                    0,
    4579                    1,
    4580                    2,
    4581                    -1,
    4582                    i8::MIN.into(),
    4583                    i8::MAX.into(),
    4584                    u8::MIN.into(),
    4585                    u8::MAX.into(),
    4586                ),
    4587                i16x8(
    4588                    i16::MIN,
    4589                    i16::MAX,
    4590                    u16::MIN as i16,
    4591                    u16::MAX as i16,
    4592                    0,
    4593                    0,
    4594                    0,
    4595                    0,
    4596                ),
    4597            ),
    4598            i8x16(0, 1, 2, -1, -128, 127, 0, 127, -128, 127, 0, -1, 0, 0, 0, 0),
    4599        );
    4600
    4601        compare_bytes(
    4602            u8x16_narrow_i16x8(
    4603                i16x8(
    4604                    0,
    4605                    1,
    4606                    2,
    4607                    -1,
    4608                    i8::MIN.into(),
    4609                    i8::MAX.into(),
    4610                    u8::MIN.into(),
    4611                    u8::MAX.into(),
    4612                ),
    4613                i16x8(
    4614                    i16::MIN,
    4615                    i16::MAX,
    4616                    u16::MIN as i16,
    4617                    u16::MAX as i16,
    4618                    0,
    4619                    0,
    4620                    0,
    4621                    0,
    4622                ),
    4623            ),
    4624            i8x16(0, 1, 2, 0, 0, 127, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0),
    4625        );
    4626
    4627        compare_bytes(i16x8_narrow_i32x4(zero, zero), zero);
    4628        compare_bytes(u16x8_narrow_i32x4(zero, zero), zero);
    4629        compare_bytes(i16x8_narrow_i32x4(ones, ones), ones);
    4630        compare_bytes(u16x8_narrow_i32x4(ones, ones), zero);
    4631
    4632        compare_bytes(
    4633            i16x8_narrow_i32x4(
    4634                i32x4(0, -1, i16::MIN.into(), i16::MAX.into()),
    4635                i32x4(i32::MIN, i32::MAX, u32::MIN as i32, u32::MAX as i32),
    4636            ),
    4637            i16x8(0, -1, i16::MIN, i16::MAX, i16::MIN, i16::MAX, 0, -1),
    4638        );
    4639
    4640        compare_bytes(
    4641            u16x8_narrow_i32x4(
    4642                i32x4(u16::MAX.into(), -1, i16::MIN.into(), i16::MAX.into()),
    4643                i32x4(i32::MIN, i32::MAX, u32::MIN as i32, u32::MAX as i32),
    4644            ),
    4645            i16x8(-1, 0, 0, i16::MAX, 0, -1, 0, 0),
    4646        );
    4647    }
    4648
    4649    #[test]
    4650    fn test_extend() {
    4651        let zero = i8x16_splat(0);
    4652        let ones = i8x16_splat(!0);
    4653
    4654        compare_bytes(i16x8_extend_low_i8x16(zero), zero);
    4655        compare_bytes(i16x8_extend_high_i8x16(zero), zero);
    4656        compare_bytes(i16x8_extend_low_u8x16(zero), zero);
    4657        compare_bytes(i16x8_extend_high_u8x16(zero), zero);
    4658        compare_bytes(i16x8_extend_low_i8x16(ones), ones);
    4659        compare_bytes(i16x8_extend_high_i8x16(ones), ones);
    4660        let halves = u16x8_splat(u8::MAX.into());
    4661        compare_bytes(i16x8_extend_low_u8x16(ones), halves);
    4662        compare_bytes(i16x8_extend_high_u8x16(ones), halves);
    4663
    4664        compare_bytes(i32x4_extend_low_i16x8(zero), zero);
    4665        compare_bytes(i32x4_extend_high_i16x8(zero), zero);
    4666        compare_bytes(i32x4_extend_low_u16x8(zero), zero);
    4667        compare_bytes(i32x4_extend_high_u16x8(zero), zero);
    4668        compare_bytes(i32x4_extend_low_i16x8(ones), ones);
    4669        compare_bytes(i32x4_extend_high_i16x8(ones), ones);
    4670        let halves = u32x4_splat(u16::MAX.into());
    4671        compare_bytes(i32x4_extend_low_u16x8(ones), halves);
    4672        compare_bytes(i32x4_extend_high_u16x8(ones), halves);
    4673
    4674        compare_bytes(i64x2_extend_low_i32x4(zero), zero);
    4675        compare_bytes(i64x2_extend_high_i32x4(zero), zero);
    4676        compare_bytes(i64x2_extend_low_u32x4(zero), zero);
    4677        compare_bytes(i64x2_extend_high_u32x4(zero), zero);
    4678        compare_bytes(i64x2_extend_low_i32x4(ones), ones);
    4679        compare_bytes(i64x2_extend_high_i32x4(ones), ones);
    4680        let halves = i64x2_splat(u32::MAX.into());
    4681        compare_bytes(u64x2_extend_low_u32x4(ones), halves);
    4682        compare_bytes(u64x2_extend_high_u32x4(ones), halves);
    4683    }
    4684
    4685    #[test]
    4686    fn test_dot() {
    4687        let zero = i8x16_splat(0);
    4688        let ones = i8x16_splat(!0);
    4689        let two = i32x4_splat(2);
    4690        compare_bytes(i32x4_dot_i16x8(zero, zero), zero);
    4691        compare_bytes(i32x4_dot_i16x8(ones, ones), two);
    4692    }
    4693
    4694    macro_rules! test_binop {
    4695        (
    4696            $($name:ident => {
    4697                $([$($vec1:tt)*] ($op:ident | $f:ident) [$($vec2:tt)*],)*
    4698            })*
    4699        ) => ($(
    4700            #[test]
    4701            fn $name() {
    4702                unsafe {
    4703                    $(
    4704                        let v1 = [$($vec1)*];
    4705                        let v2 = [$($vec2)*];
    4706                        let v1_v128: v128 = mem::transmute(v1);
    4707                        let v2_v128: v128 = mem::transmute(v2);
    4708                        let v3_v128 = super::$f(v1_v128, v2_v128);
    4709                        let mut v3 = [$($vec1)*];
    4710                        let _ignore = v3;
    4711                        v3 = mem::transmute(v3_v128);
    4712
    4713                        for (i, actual) in v3.iter().enumerate() {
    4714                            let expected = v1[i].$op(v2[i]);
    4715                            assert_eq!(*actual, expected);
    4716                        }
    4717                    )*
    4718                }
    4719            }
    4720        )*)
    4721    }
    4722
    4723    macro_rules! test_unop {
    4724        (
    4725            $($name:ident => {
    4726                $(($op:ident | $f:ident) [$($vec1:tt)*],)*
    4727            })*
    4728        ) => ($(
    4729            #[test]
    4730            fn $name() {
    4731                unsafe {
    4732                    $(
    4733                        let v1 = [$($vec1)*];
    4734                        let v1_v128: v128 = mem::transmute(v1);
    4735                        let v2_v128 = super::$f(v1_v128);
    4736                        let mut v2 = [$($vec1)*];
    4737                        let _ignore = v2;
    4738                        v2 = mem::transmute(v2_v128);
    4739
    4740                        for (i, actual) in v2.iter().enumerate() {
    4741                            let expected = v1[i].$op();
    4742                            assert_eq!(*actual, expected);
    4743                        }
    4744                    )*
    4745                }
    4746            }
    4747        )*)
    4748    }
    4749
    4750    trait Avgr: Sized {
    4751        fn avgr(self, other: Self) -> Self;
    4752    }
    4753
    4754    macro_rules! impl_avgr {
    4755        ($($i:ident)*) => ($(impl Avgr for $i {
    4756            fn avgr(self, other: Self) -> Self {
    4757                ((self as u64 + other as u64 + 1) / 2) as $i
    4758            }
    4759        })*)
    4760    }
    4761
    4762    impl_avgr!(u8 u16);
    4763
    4764    test_binop! {
    4765        test_i8x16_add => {
    4766            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4767                (wrapping_add | i8x16_add)
    4768            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4769
    4770            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4771                (wrapping_add | i8x16_add)
    4772            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4773
    4774            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4775                (wrapping_add | i8x16_add)
    4776            [127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 9, -24],
    4777        }
    4778
    4779        test_i8x16_add_sat_s => {
    4780            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4781                (saturating_add | i8x16_add_sat)
    4782            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4783
    4784            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4785                (saturating_add | i8x16_add_sat)
    4786            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4787
    4788            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4789                (saturating_add | i8x16_add_sat)
    4790            [127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 9, -24],
    4791        }
    4792
    4793        test_i8x16_add_sat_u => {
    4794            [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4795                (saturating_add | u8x16_add_sat)
    4796            [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4797
    4798            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4799                (saturating_add | u8x16_add_sat)
    4800            [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
    4801
    4802            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4803                (saturating_add | u8x16_add_sat)
    4804            [127, -44i8 as u8, 43, 126, 4, 2, 9, -3i8 as u8, -59i8 as u8, -43i8 as u8, 39, -69i8 as u8, 79, -3i8 as u8, 9, -24i8 as u8],
    4805        }
    4806
    4807        test_i8x16_sub => {
    4808            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4809                (wrapping_sub | i8x16_sub)
    4810            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4811
    4812            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4813                (wrapping_sub | i8x16_sub)
    4814            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4815
    4816            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4817                (wrapping_sub | i8x16_sub)
    4818            [-127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 4, 8],
    4819        }
    4820
    4821        test_i8x16_sub_sat_s => {
    4822            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4823                (saturating_sub | i8x16_sub_sat)
    4824            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4825
    4826            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4827                (saturating_sub | i8x16_sub_sat)
    4828            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4829
    4830            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4831                (saturating_sub | i8x16_sub_sat)
    4832            [-127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 4, 8],
    4833        }
    4834
    4835        test_i8x16_sub_sat_u => {
    4836            [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4837                (saturating_sub | u8x16_sub_sat)
    4838            [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4839
    4840            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4841                (saturating_sub | u8x16_sub_sat)
    4842            [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
    4843
    4844            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4845                (saturating_sub | u8x16_sub_sat)
    4846            [127, -44i8 as u8, 43, 126, 4, 2, 9, -3i8 as u8, -59i8 as u8, -43i8 as u8, 39, -69i8 as u8, 79, -3i8 as u8, 9, -24i8 as u8],
    4847        }
    4848
    4849        test_i8x16_min_s => {
    4850            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4851                (min | i8x16_min)
    4852            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4853
    4854            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4855                (min | i8x16_min)
    4856            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4857
    4858            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4859                (min | i8x16_min)
    4860            [-127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 4, 8],
    4861        }
    4862
    4863        test_i8x16_min_u => {
    4864            [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4865                (min | u8x16_min)
    4866            [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4867
    4868            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4869                (min | u8x16_min)
    4870            [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
    4871
    4872            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4873                (min | u8x16_min)
    4874            [127, -44i8 as u8, 43, 126, 4, 2, 9, -3i8 as u8, -59i8 as u8, -43i8 as u8, 39, -69i8 as u8, 79, -3i8 as u8, 9, -24i8 as u8],
    4875        }
    4876
    4877        test_i8x16_max_s => {
    4878            [0i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4879                (max | i8x16_max)
    4880            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4881
    4882            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4883                (max | i8x16_max)
    4884            [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    4885
    4886            [1i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4887                (max | i8x16_max)
    4888            [-127, -44, 43, 126, 4, 2, 9, -3, -59, -43, 39, -69, 79, -3, 4, 8],
    4889        }
    4890
    4891        test_i8x16_max_u => {
    4892            [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4893                (max | u8x16_max)
    4894            [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4895
    4896            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4897                (max | u8x16_max)
    4898            [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
    4899
    4900            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4901                (max | u8x16_max)
    4902            [127, -44i8 as u8, 43, 126, 4, 2, 9, -3i8 as u8, -59i8 as u8, -43i8 as u8, 39, -69i8 as u8, 79, -3i8 as u8, 9, -24i8 as u8],
    4903        }
    4904
    4905        test_i8x16_avgr_u => {
    4906            [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    4907                (avgr | u8x16_avgr)
    4908            [1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    4909
    4910            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4911                (avgr | u8x16_avgr)
    4912            [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
    4913
    4914            [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    4915                (avgr | u8x16_avgr)
    4916            [127, -44i8 as u8, 43, 126, 4, 2, 9, -3i8 as u8, -59i8 as u8, -43i8 as u8, 39, -69i8 as u8, 79, -3i8 as u8, 9, -24i8 as u8],
    4917        }
    4918
    4919        test_i16x8_add => {
    4920            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4921                (wrapping_add | i16x8_add)
    4922            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4923
    4924            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4925                (wrapping_add | i16x8_add)
    4926            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4927        }
    4928
    4929        test_i16x8_add_sat_s => {
    4930            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4931                (saturating_add | i16x8_add_sat)
    4932            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4933
    4934            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4935                (saturating_add | i16x8_add_sat)
    4936            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4937        }
    4938
    4939        test_i16x8_add_sat_u => {
    4940            [0u16, 0, 0, 0, 0, 0, 0, 0]
    4941                (saturating_add | u16x8_add_sat)
    4942            [1u16, 1, 1, 1, 1, 1, 1, 1],
    4943
    4944            [1u16, 2, 3, 4, 5, 6, 7, 8]
    4945                (saturating_add | u16x8_add_sat)
    4946            [32767, 8, -2494i16 as u16,-4i16 as u16, 4882, -4i16 as u16, 848, 3830],
    4947        }
    4948
    4949        test_i16x8_sub => {
    4950            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4951                (wrapping_sub | i16x8_sub)
    4952            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4953
    4954            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4955                (wrapping_sub | i16x8_sub)
    4956            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4957        }
    4958
    4959        test_i16x8_sub_sat_s => {
    4960            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4961                (saturating_sub | i16x8_sub_sat)
    4962            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4963
    4964            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4965                (saturating_sub | i16x8_sub_sat)
    4966            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4967        }
    4968
    4969        test_i16x8_sub_sat_u => {
    4970            [0u16, 0, 0, 0, 0, 0, 0, 0]
    4971                (saturating_sub | u16x8_sub_sat)
    4972            [1u16, 1, 1, 1, 1, 1, 1, 1],
    4973
    4974            [1u16, 2, 3, 4, 5, 6, 7, 8]
    4975                (saturating_sub | u16x8_sub_sat)
    4976            [32767, 8, -2494i16 as u16,-4i16 as u16, 4882, -4i16 as u16, 848, 3830],
    4977        }
    4978
    4979        test_i16x8_mul => {
    4980            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4981                (wrapping_mul | i16x8_mul)
    4982            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4983
    4984            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4985                (wrapping_mul | i16x8_mul)
    4986            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4987        }
    4988
    4989        test_i16x8_min_s => {
    4990            [0i16, 0, 0, 0, 0, 0, 0, 0]
    4991                (min | i16x8_min)
    4992            [1i16, 1, 1, 1, 1, 1, 1, 1],
    4993
    4994            [1i16, 2, 3, 4, 5, 6, 7, 8]
    4995                (min | i16x8_min)
    4996            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    4997        }
    4998
    4999        test_i16x8_min_u => {
    5000            [0u16, 0, 0, 0, 0, 0, 0, 0]
    5001                (min | u16x8_min)
    5002            [1u16, 1, 1, 1, 1, 1, 1, 1],
    5003
    5004            [1u16, 2, 3, 4, 5, 6, 7, 8]
    5005                (min | u16x8_min)
    5006            [32767, 8, -2494i16 as u16,-4i16 as u16, 4882, -4i16 as u16, 848, 3830],
    5007        }
    5008
    5009        test_i16x8_max_s => {
    5010            [0i16, 0, 0, 0, 0, 0, 0, 0]
    5011                (max | i16x8_max)
    5012            [1i16, 1, 1, 1, 1, 1, 1, 1],
    5013
    5014            [1i16, 2, 3, 4, 5, 6, 7, 8]
    5015                (max | i16x8_max)
    5016            [32767, 8, -2494,-4, 4882, -4, 848, 3830],
    5017        }
    5018
    5019        test_i16x8_max_u => {
    5020            [0u16, 0, 0, 0, 0, 0, 0, 0]
    5021                (max | u16x8_max)
    5022            [1u16, 1, 1, 1, 1, 1, 1, 1],
    5023
    5024            [1u16, 2, 3, 4, 5, 6, 7, 8]
    5025                (max | u16x8_max)
    5026            [32767, 8, -2494i16 as u16,-4i16 as u16, 4882, -4i16 as u16, 848, 3830],
    5027        }
    5028
    5029        test_i16x8_avgr_u => {
    5030            [0u16, 0, 0, 0, 0, 0, 0, 0]
    5031                (avgr | u16x8_avgr)
    5032            [1u16, 1, 1, 1, 1, 1, 1, 1],
    5033
    5034            [1u16, 2, 3, 4, 5, 6, 7, 8]
    5035                (avgr | u16x8_avgr)
    5036            [32767, 8, -2494i16 as u16,-4i16 as u16, 4882, -4i16 as u16, 848, 3830],
    5037        }
    5038
    5039        test_i32x4_add => {
    5040            [0i32, 0, 0, 0] (wrapping_add | i32x4_add) [1, 2, 3, 4],
    5041            [1i32, 1283, i32::MAX, i32::MIN]
    5042                (wrapping_add | i32x4_add)
    5043            [i32::MAX; 4],
    5044        }
    5045
    5046        test_i32x4_sub => {
    5047            [0i32, 0, 0, 0] (wrapping_sub | i32x4_sub) [1, 2, 3, 4],
    5048            [1i32, 1283, i32::MAX, i32::MIN]
    5049                (wrapping_sub | i32x4_sub)
    5050            [i32::MAX; 4],
    5051        }
    5052
    5053        test_i32x4_mul => {
    5054            [0i32, 0, 0, 0] (wrapping_mul | i32x4_mul) [1, 2, 3, 4],
    5055            [1i32, 1283, i32::MAX, i32::MIN]
    5056                (wrapping_mul | i32x4_mul)
    5057            [i32::MAX; 4],
    5058        }
    5059
    5060        test_i32x4_min_s => {
    5061            [0i32, 0, 0, 0] (min | i32x4_min) [1, 2, 3, 4],
    5062            [1i32, 1283, i32::MAX, i32::MIN]
    5063                (min | i32x4_min)
    5064            [i32::MAX; 4],
    5065        }
    5066
    5067        test_i32x4_min_u => {
    5068            [0u32, 0, 0, 0] (min | u32x4_min) [1, 2, 3, 4],
    5069            [1u32, 1283, i32::MAX as u32, i32::MIN as u32]
    5070                (min | u32x4_min)
    5071            [i32::MAX as u32; 4],
    5072        }
    5073
    5074        test_i32x4_max_s => {
    5075            [0i32, 0, 0, 0] (max | i32x4_max) [1, 2, 3, 4],
    5076            [1i32, 1283, i32::MAX, i32::MIN]
    5077                (max | i32x4_max)
    5078            [i32::MAX; 4],
    5079        }
    5080
    5081        test_i32x4_max_u => {
    5082            [0u32, 0, 0, 0] (max | u32x4_max) [1, 2, 3, 4],
    5083            [1u32, 1283, i32::MAX as u32, i32::MIN as u32]
    5084                (max | u32x4_max)
    5085            [i32::MAX as u32; 4],
    5086        }
    5087
    5088        test_i64x2_add => {
    5089            [0i64, 0] (wrapping_add | i64x2_add) [1, 2],
    5090            [i64::MIN, i64::MAX] (wrapping_add | i64x2_add) [i64::MAX, i64::MIN],
    5091            [i64::MAX; 2] (wrapping_add | i64x2_add) [i64::MAX; 2],
    5092            [-4i64, -4] (wrapping_add | i64x2_add) [800, 939],
    5093        }
    5094
    5095        test_i64x2_sub => {
    5096            [0i64, 0] (wrapping_sub | i64x2_sub) [1, 2],
    5097            [i64::MIN, i64::MAX] (wrapping_sub | i64x2_sub) [i64::MAX, i64::MIN],
    5098            [i64::MAX; 2] (wrapping_sub | i64x2_sub) [i64::MAX; 2],
    5099            [-4i64, -4] (wrapping_sub | i64x2_sub) [800, 939],
    5100        }
    5101
    5102        test_i64x2_mul => {
    5103            [0i64, 0] (wrapping_mul | i64x2_mul) [1, 2],
    5104            [i64::MIN, i64::MAX] (wrapping_mul | i64x2_mul) [i64::MAX, i64::MIN],
    5105            [i64::MAX; 2] (wrapping_mul | i64x2_mul) [i64::MAX; 2],
    5106            [-4i64, -4] (wrapping_mul | i64x2_mul) [800, 939],
    5107        }
    5108
    5109        test_f32x4_add => {
    5110            [-1.0f32, 2.0, 3.0, 4.0] (add | f32x4_add) [1., 2., 0., 0.],
    5111            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5112                (add | f32x4_add)
    5113            [1., 2., 0., 0.],
    5114        }
    5115
    5116        test_f32x4_sub => {
    5117            [-1.0f32, 2.0, 3.0, 4.0] (sub | f32x4_sub) [1., 2., 0., 0.],
    5118            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5119                (sub | f32x4_sub)
    5120            [1., 2., 0., 0.],
    5121        }
    5122
    5123        test_f32x4_mul => {
    5124            [-1.0f32, 2.0, 3.0, 4.0] (mul | f32x4_mul) [1., 2., 0., 0.],
    5125            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5126                (mul | f32x4_mul)
    5127            [1., 2., 1., 0.],
    5128        }
    5129
    5130        test_f32x4_div => {
    5131            [-1.0f32, 2.0, 3.0, 4.0] (div | f32x4_div) [1., 2., 0., 0.],
    5132            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5133                (div | f32x4_div)
    5134            [1., 2., 0., 0.],
    5135        }
    5136
    5137        test_f32x4_min => {
    5138            [-1.0f32, 2.0, 3.0, 4.0] (min | f32x4_min) [1., 2., 0., 0.],
    5139            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5140                (min | f32x4_min)
    5141            [1., 2., 0., 0.],
    5142        }
    5143
    5144        test_f32x4_max => {
    5145            [-1.0f32, 2.0, 3.0, 4.0] (max | f32x4_max) [1., 2., 0., 0.],
    5146            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5147                (max | f32x4_max)
    5148            [1., 2., 0., 0.],
    5149        }
    5150
    5151        test_f32x4_pmin => {
    5152            [-1.0f32, 2.0, 3.0, 4.0] (min | f32x4_pmin) [1., 2., 0., 0.],
    5153            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5154                (min | f32x4_pmin)
    5155            [1., 2., 0., 0.],
    5156        }
    5157
    5158        test_f32x4_pmax => {
    5159            [-1.0f32, 2.0, 3.0, 4.0] (max | f32x4_pmax) [1., 2., 0., 0.],
    5160            [f32::INFINITY, -0.0, f32::NEG_INFINITY, 3.0]
    5161                (max | f32x4_pmax)
    5162            [1., 2., 0., 0.],
    5163        }
    5164
    5165        test_f64x2_add => {
    5166            [-1.0f64, 2.0] (add | f64x2_add) [1., 2.],
    5167            [f64::INFINITY, f64::NEG_INFINITY] (add | f64x2_add) [1., 2.],
    5168        }
    5169
    5170        test_f64x2_sub => {
    5171            [-1.0f64, 2.0] (sub | f64x2_sub) [1., 2.],
    5172            [f64::INFINITY, f64::NEG_INFINITY] (sub | f64x2_sub) [1., 2.],
    5173        }
    5174
    5175        test_f64x2_mul => {
    5176            [-1.0f64, 2.0] (mul | f64x2_mul) [1., 2.],
    5177            [f64::INFINITY, f64::NEG_INFINITY] (mul | f64x2_mul) [1., 2.],
    5178        }
    5179
    5180        test_f64x2_div => {
    5181            [-1.0f64, 2.0] (div | f64x2_div) [1., 2.],
    5182            [f64::INFINITY, f64::NEG_INFINITY] (div | f64x2_div) [1., 2.],
    5183        }
    5184
    5185        test_f64x2_min => {
    5186            [-1.0f64, 2.0] (min | f64x2_min) [1., 2.],
    5187            [f64::INFINITY, f64::NEG_INFINITY] (min | f64x2_min) [1., 2.],
    5188        }
    5189
    5190        test_f64x2_max => {
    5191            [-1.0f64, 2.0] (max | f64x2_max) [1., 2.],
    5192            [f64::INFINITY, f64::NEG_INFINITY] (max | f64x2_max) [1., 2.],
    5193        }
    5194
    5195        test_f64x2_pmin => {
    5196            [-1.0f64, 2.0] (min | f64x2_pmin) [1., 2.],
    5197            [f64::INFINITY, f64::NEG_INFINITY] (min | f64x2_pmin) [1., 2.],
    5198        }
    5199
    5200        test_f64x2_pmax => {
    5201            [-1.0f64, 2.0] (max | f64x2_pmax) [1., 2.],
    5202            [f64::INFINITY, f64::NEG_INFINITY] (max | f64x2_pmax) [1., 2.],
    5203        }
    5204    }
    5205
    5206    test_unop! {
    5207        test_i8x16_abs => {
    5208            (wrapping_abs | i8x16_abs)
    5209            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    5210
    5211            (wrapping_abs | i8x16_abs)
    5212            [-2i8, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    5213
    5214            (wrapping_abs | i8x16_abs)
    5215            [-127i8, -44, 43, 126, 4, -128, 127, -59, -43, 39, -69, 79, -3, 35, 83, 13],
    5216        }
    5217
    5218        test_i8x16_neg => {
    5219            (wrapping_neg | i8x16_neg)
    5220            [1i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    5221
    5222            (wrapping_neg | i8x16_neg)
    5223            [-2i8, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -18],
    5224
    5225            (wrapping_neg | i8x16_neg)
    5226            [-127i8, -44, 43, 126, 4, -128, 127, -59, -43, 39, -69, 79, -3, 35, 83, 13],
    5227        }
    5228
    5229        test_i16x8_abs => {
    5230            (wrapping_abs | i16x8_abs) [1i16, 1, 1, 1, 1, 1, 1, 1],
    5231            (wrapping_abs | i16x8_abs) [2i16, 0x7fff, !0, 4, 42, -5, 33, -4847],
    5232        }
    5233
    5234        test_i16x8_neg => {
    5235            (wrapping_neg | i16x8_neg) [1i16, 1, 1, 1, 1, 1, 1, 1],
    5236            (wrapping_neg | i16x8_neg) [2i16, 0x7fff, !0, 4, 42, -5, 33, -4847],
    5237        }
    5238
    5239        test_i32x4_abs => {
    5240            (wrapping_abs | i32x4_abs) [1i32, 2, 3, 4],
    5241            (wrapping_abs | i32x4_abs) [i32::MIN, i32::MAX, 0, 4],
    5242        }
    5243
    5244        test_i32x4_neg => {
    5245            (wrapping_neg | i32x4_neg) [1i32, 2, 3, 4],
    5246            (wrapping_neg | i32x4_neg) [i32::MIN, i32::MAX, 0, 4],
    5247        }
    5248
    5249        test_i64x2_abs => {
    5250            (wrapping_abs | i64x2_abs) [1i64, 2],
    5251            (wrapping_abs | i64x2_abs) [i64::MIN, i64::MAX],
    5252        }
    5253
    5254        test_i64x2_neg => {
    5255            (wrapping_neg | i64x2_neg) [1i64, 2],
    5256            (wrapping_neg | i64x2_neg) [i64::MIN, i64::MAX],
    5257        }
    5258
    5259        test_f32x4_ceil => {
    5260            (ceil | f32x4_ceil) [1.0f32, 2., 2.5, 3.3],
    5261            (ceil | f32x4_ceil) [0.0, -0.3, f32::INFINITY, -0.0],
    5262        }
    5263
    5264        test_f32x4_floor => {
    5265            (floor | f32x4_floor) [1.0f32, 2., 2.5, 3.3],
    5266            (floor | f32x4_floor) [0.0, -0.3, f32::INFINITY, -0.0],
    5267        }
    5268
    5269        test_f32x4_trunc => {
    5270            (trunc | f32x4_trunc) [1.0f32, 2., 2.5, 3.3],
    5271            (trunc | f32x4_trunc) [0.0, -0.3, f32::INFINITY, -0.0],
    5272        }
    5273
    5274        test_f32x4_nearest => {
    5275            (round | f32x4_nearest) [1.0f32, 2., 2.6, 3.3],
    5276            (round | f32x4_nearest) [0.0, -0.3, f32::INFINITY, -0.0],
    5277        }
    5278
    5279        test_f32x4_abs => {
    5280            (abs | f32x4_abs) [1.0f32, 2., 2.6, 3.3],
    5281            (abs | f32x4_abs) [0.0, -0.3, f32::INFINITY, -0.0],
    5282        }
    5283
    5284        test_f32x4_neg => {
    5285            (neg | f32x4_neg) [1.0f32, 2., 2.6, 3.3],
    5286            (neg | f32x4_neg) [0.0, -0.3, f32::INFINITY, -0.0],
    5287        }
    5288
    5289        test_f32x4_sqrt => {
    5290            (sqrt | f32x4_sqrt) [1.0f32, 2., 2.6, 3.3],
    5291            (sqrt | f32x4_sqrt) [0.0, 0.3, f32::INFINITY, 0.1],
    5292        }
    5293
    5294        test_f64x2_ceil => {
    5295            (ceil | f64x2_ceil) [1.0f64, 2.3],
    5296            (ceil | f64x2_ceil) [f64::INFINITY, -0.1],
    5297        }
    5298
    5299        test_f64x2_floor => {
    5300            (floor | f64x2_floor) [1.0f64, 2.3],
    5301            (floor | f64x2_floor) [f64::INFINITY, -0.1],
    5302        }
    5303
    5304        test_f64x2_trunc => {
    5305            (trunc | f64x2_trunc) [1.0f64, 2.3],
    5306            (trunc | f64x2_trunc) [f64::INFINITY, -0.1],
    5307        }
    5308
    5309        test_f64x2_nearest => {
    5310            (round | f64x2_nearest) [1.0f64, 2.3],
    5311            (round | f64x2_nearest) [f64::INFINITY, -0.1],
    5312        }
    5313
    5314        test_f64x2_abs => {
    5315            (abs | f64x2_abs) [1.0f64, 2.3],
    5316            (abs | f64x2_abs) [f64::INFINITY, -0.1],
    5317        }
    5318
    5319        test_f64x2_neg => {
    5320            (neg | f64x2_neg) [1.0f64, 2.3],
    5321            (neg | f64x2_neg) [f64::INFINITY, -0.1],
    5322        }
    5323
    5324        test_f64x2_sqrt => {
    5325            (sqrt | f64x2_sqrt) [1.0f64, 2.3],
    5326            (sqrt | f64x2_sqrt) [f64::INFINITY, 0.1],
    5327        }
    5328    }
    5329
    5330    macro_rules! floating_point {
    5331        (f32) => {
    5332            true
    5333        };
    5334        (f64) => {
    5335            true
    5336        };
    5337        ($id:ident) => {
    5338            false
    5339        };
    5340    }
    5341
    5342    trait IsNan: Sized {
    5343        fn is_nan(self) -> bool {
    5344            false
    5345        }
    5346    }
    5347    impl IsNan for i8 {}
    5348    impl IsNan for i16 {}
    5349    impl IsNan for i32 {}
    5350    impl IsNan for i64 {}
    5351
    5352    macro_rules! test_bop {
    5353         ($id:ident[$ety:ident; $ecount:expr] |
    5354          $binary_op:ident [$op_test_id:ident] :
    5355          ([$($in_a:expr),*], [$($in_b:expr),*]) => [$($out:expr),*]) => {
    5356             test_bop!(
    5357                 $id[$ety; $ecount] => $ety | $binary_op [ $op_test_id ]:
    5358                 ([$($in_a),*], [$($in_b),*]) => [$($out),*]
    5359             );
    5360
    5361         };
    5362         ($id:ident[$ety:ident; $ecount:expr] => $oty:ident |
    5363          $binary_op:ident [$op_test_id:ident] :
    5364          ([$($in_a:expr),*], [$($in_b:expr),*]) => [$($out:expr),*]) => {
    5365             #[test]
    5366             fn $op_test_id() {
    5367                 unsafe {
    5368                     let a_input: [$ety; $ecount] = [$($in_a),*];
    5369                     let b_input: [$ety; $ecount] = [$($in_b),*];
    5370                     let output: [$oty; $ecount] = [$($out),*];
    5371
    5372                     let a_vec_in: v128 = transmute(a_input);
    5373                     let b_vec_in: v128 = transmute(b_input);
    5374                     let vec_res: v128 = $binary_op(a_vec_in, b_vec_in);
    5375
    5376                     let res: [$oty; $ecount] = transmute(vec_res);
    5377
    5378                     if !floating_point!($ety) {
    5379                         assert_eq!(res, output);
    5380                     } else {
    5381                         for i in 0..$ecount {
    5382                             let r = res[i];
    5383                             let o = output[i];
    5384                             assert_eq!(r.is_nan(), o.is_nan());
    5385                             if !r.is_nan() {
    5386                                 assert_eq!(r, o);
    5387                             }
    5388                         }
    5389                     }
    5390                 }
    5391             }
    5392         }
    5393     }
    5394
    5395    macro_rules! test_bops {
    5396         ($id:ident[$ety:ident; $ecount:expr] |
    5397          $binary_op:ident [$op_test_id:ident]:
    5398          ([$($in_a:expr),*], $in_b:expr) => [$($out:expr),*]) => {
    5399             #[test]
    5400             fn $op_test_id() {
    5401                 unsafe {
    5402                     let a_input: [$ety; $ecount] = [$($in_a),*];
    5403                     let output: [$ety; $ecount] = [$($out),*];
    5404
    5405                     let a_vec_in: v128 = transmute(a_input);
    5406                     let vec_res: v128 = $binary_op(a_vec_in, $in_b);
    5407
    5408                     let res: [$ety; $ecount] = transmute(vec_res);
    5409                     assert_eq!(res, output);
    5410                 }
    5411             }
    5412         }
    5413     }
    5414
    5415    macro_rules! test_uop {
    5416         ($id:ident[$ety:ident; $ecount:expr] |
    5417          $unary_op:ident [$op_test_id:ident]: [$($in_a:expr),*] => [$($out:expr),*]) => {
    5418             #[test]
    5419             fn $op_test_id() {
    5420                 unsafe {
    5421                     let a_input: [$ety; $ecount] = [$($in_a),*];
    5422                     let output: [$ety; $ecount] = [$($out),*];
    5423
    5424                     let a_vec_in: v128 = transmute(a_input);
    5425                     let vec_res: v128 = $unary_op(a_vec_in);
    5426
    5427                     let res: [$ety; $ecount] = transmute(vec_res);
    5428                     assert_eq!(res, output);
    5429                 }
    5430             }
    5431         }
    5432     }
    5433
    5434    test_bops!(i8x16[i8; 16] | i8x16_shl[i8x16_shl_test]:
    5435               ([0, -1, 2, 3, 4, 5, 6, i8::MAX, 1, 1, 1, 1, 1, 1, 1, 1], 1) =>
    5436               [0, -2, 4, 6, 8, 10, 12, -2, 2, 2, 2, 2, 2, 2, 2, 2]);
    5437    test_bops!(i16x8[i16; 8] | i16x8_shl[i16x8_shl_test]:
    5438                ([0, -1, 2, 3, 4, 5, 6, i16::MAX], 1) =>
    5439                [0, -2, 4, 6, 8, 10, 12, -2]);
    5440    test_bops!(i32x4[i32; 4] | i32x4_shl[i32x4_shl_test]:
    5441                ([0, -1, 2, 3], 1) => [0, -2, 4, 6]);
    5442    test_bops!(i64x2[i64; 2] | i64x2_shl[i64x2_shl_test]:
    5443                ([0, -1], 1) => [0, -2]);
    5444
    5445    test_bops!(i8x16[i8; 16] | i8x16_shr[i8x16_shr_s_test]:
    5446               ([0, -1, 2, 3, 4, 5, 6, i8::MAX, 1, 1, 1, 1, 1, 1, 1, 1], 1) =>
    5447               [0, -1, 1, 1, 2, 2, 3, 63, 0, 0, 0, 0, 0, 0, 0, 0]);
    5448    test_bops!(i16x8[i16; 8] | i16x8_shr[i16x8_shr_s_test]:
    5449               ([0, -1, 2, 3, 4, 5, 6, i16::MAX], 1) =>
    5450               [0, -1, 1, 1, 2, 2, 3, i16::MAX / 2]);
    5451    test_bops!(i32x4[i32; 4] | i32x4_shr[i32x4_shr_s_test]:
    5452               ([0, -1, 2, 3], 1) => [0, -1, 1, 1]);
    5453    test_bops!(i64x2[i64; 2] | i64x2_shr[i64x2_shr_s_test]:
    5454               ([0, -1], 1) => [0, -1]);
    5455
    5456    test_bops!(i8x16[i8; 16] | u8x16_shr[i8x16_uhr_u_test]:
    5457                ([0, -1, 2, 3, 4, 5, 6, i8::MAX, 1, 1, 1, 1, 1, 1, 1, 1], 1) =>
    5458                [0, i8::MAX, 1, 1, 2, 2, 3, 63, 0, 0, 0, 0, 0, 0, 0, 0]);
    5459    test_bops!(i16x8[i16; 8] | u16x8_shr[i16x8_uhr_u_test]:
    5460                ([0, -1, 2, 3, 4, 5, 6, i16::MAX], 1) =>
    5461                [0, i16::MAX, 1, 1, 2, 2, 3, i16::MAX / 2]);
    5462    test_bops!(i32x4[i32; 4] | u32x4_shr[i32x4_uhr_u_test]:
    5463                ([0, -1, 2, 3], 1) => [0, i32::MAX, 1, 1]);
    5464    test_bops!(i64x2[i64; 2] | u64x2_shr[i64x2_uhr_u_test]:
    5465                ([0, -1], 1) => [0, i64::MAX]);
    5466
    5467    #[test]
    5468    fn v128_bitwise_logical_ops() {
    5469        unsafe {
    5470            let a: [u32; 4] = [u32::MAX, 0, u32::MAX, 0];
    5471            let b: [u32; 4] = [u32::MAX; 4];
    5472            let c: [u32; 4] = [0; 4];
    5473
    5474            let vec_a: v128 = transmute(a);
    5475            let vec_b: v128 = transmute(b);
    5476            let vec_c: v128 = transmute(c);
    5477
    5478            let r: v128 = v128_and(vec_a, vec_a);
    5479            compare_bytes(r, vec_a);
    5480            let r: v128 = v128_and(vec_a, vec_b);
    5481            compare_bytes(r, vec_a);
    5482            let r: v128 = v128_andnot(vec_a, vec_b);
    5483            compare_bytes(r, vec_c);
    5484            let r: v128 = v128_andnot(vec_a, vec_a);
    5485            compare_bytes(r, vec_c);
    5486            let r: v128 = v128_andnot(vec_a, vec_c);
    5487            compare_bytes(r, vec_a);
    5488            let r: v128 = v128_or(vec_a, vec_b);
    5489            compare_bytes(r, vec_b);
    5490            let r: v128 = v128_not(vec_b);
    5491            compare_bytes(r, vec_c);
    5492            let r: v128 = v128_xor(vec_a, vec_c);
    5493            compare_bytes(r, vec_a);
    5494
    5495            let r: v128 = v128_bitselect(vec_b, vec_c, vec_b);
    5496            compare_bytes(r, vec_b);
    5497            let r: v128 = v128_bitselect(vec_b, vec_c, vec_c);
    5498            compare_bytes(r, vec_c);
    5499            let r: v128 = v128_bitselect(vec_b, vec_c, vec_a);
    5500            compare_bytes(r, vec_a);
    5501        }
    5502    }
    5503
    5504    macro_rules! test_bool_red {
    5505         ([$test_id:ident, $any:ident, $all:ident] | [$($true:expr),*] | [$($false:expr),*] | [$($alt:expr),*]) => {
    5506             #[test]
    5507             fn $test_id() {
    5508                 unsafe {
    5509                     let vec_a: v128 = transmute([$($true),*]); // true
    5510                     let vec_b: v128 = transmute([$($false),*]); // false
    5511                     let vec_c: v128 = transmute([$($alt),*]); // alternating
    5512
    5513                     // TODO
    5514                     // assert_eq!($any(vec_a), true);
    5515                     // assert_eq!($any(vec_b), false);
    5516                     // assert_eq!($any(vec_c), true);
    5517
    5518                     assert_eq!($all(vec_a), true);
    5519                     assert_eq!($all(vec_b), false);
    5520                     assert_eq!($all(vec_c), false);
    5521                 }
    5522             }
    5523         }
    5524     }
    5525
    5526    test_bool_red!(
    5527        [i8x16_boolean_reductions, v128_any_true, i8x16_all_true]
    5528            | [1_i8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    5529            | [0_i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    5530            | [1_i8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
    5531    );
    5532    test_bool_red!(
    5533        [i16x8_boolean_reductions, v128_any_true, i16x8_all_true]
    5534            | [1_i16, 1, 1, 1, 1, 1, 1, 1]
    5535            | [0_i16, 0, 0, 0, 0, 0, 0, 0]
    5536            | [1_i16, 0, 1, 0, 1, 0, 1, 0]
    5537    );
    5538    test_bool_red!(
    5539        [i32x4_boolean_reductions, v128_any_true, i32x4_all_true]
    5540            | [1_i32, 1, 1, 1]
    5541            | [0_i32, 0, 0, 0]
    5542            | [1_i32, 0, 1, 0]
    5543    );
    5544    test_bool_red!(
    5545        [i64x2_boolean_reductions, v128_any_true, i64x2_all_true]
    5546            | [1_i64, 1]
    5547            | [0_i64, 0]
    5548            | [1_i64, 0]
    5549    );
    5550
    5551    test_bop!(i8x16[i8; 16] | i8x16_eq[i8x16_eq_test]:
    5552              ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    5553               [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5554              [-1, 0, -1, 0 ,-1, 0, -1, -1, -1, 0, -1, 0 ,-1, 0, -1, -1]);
    5555    test_bop!(i16x8[i16; 8] | i16x8_eq[i16x8_eq_test]:
    5556               ([0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5557               [-1, 0, -1, 0 ,-1, 0, -1, -1]);
    5558    test_bop!(i32x4[i32; 4] | i32x4_eq[i32x4_eq_test]:
    5559               ([0, 1, 2, 3], [0, 2, 2, 4]) => [-1, 0, -1, 0]);
    5560    test_bop!(i64x2[i64; 2] | i64x2_eq[i64x2_eq_test]:
    5561               ([0, 1], [0, 2]) => [-1, 0]);
    5562    test_bop!(f32x4[f32; 4] => i32 | f32x4_eq[f32x4_eq_test]:
    5563               ([0., 1., 2., 3.], [0., 2., 2., 4.]) => [-1, 0, -1, 0]);
    5564    test_bop!(f64x2[f64; 2] => i64 | f64x2_eq[f64x2_eq_test]: ([0., 1.], [0., 2.]) => [-1, 0]);
    5565
    5566    test_bop!(i8x16[i8; 16] | i8x16_ne[i8x16_ne_test]:
    5567               ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    5568                [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5569               [0, -1, 0, -1 ,0, -1, 0, 0, 0, -1, 0, -1 ,0, -1, 0, 0]);
    5570    test_bop!(i16x8[i16; 8] | i16x8_ne[i16x8_ne_test]:
    5571               ([0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5572               [0, -1, 0, -1 ,0, -1, 0, 0]);
    5573    test_bop!(i32x4[i32; 4] | i32x4_ne[i32x4_ne_test]:
    5574               ([0, 1, 2, 3], [0, 2, 2, 4]) => [0, -1, 0, -1]);
    5575    test_bop!(i64x2[i64; 2] | i64x2_ne[i64x2_ne_test]:
    5576               ([0, 1], [0, 2]) => [0, -1]);
    5577    test_bop!(f32x4[f32; 4] => i32 | f32x4_ne[f32x4_ne_test]:
    5578               ([0., 1., 2., 3.], [0., 2., 2., 4.]) => [0, -1, 0, -1]);
    5579    test_bop!(f64x2[f64; 2] => i64 | f64x2_ne[f64x2_ne_test]: ([0., 1.], [0., 2.]) => [0, -1]);
    5580
    5581    test_bop!(i8x16[i8; 16] | i8x16_lt[i8x16_lt_s_test]:
    5582               ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -12, 13, 14, 15],
    5583                [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5584               [0, -1, 0, -1 ,0, -1, 0, 0, 0, -1, 0, -1, -1, -1, 0, 0]);
    5585    test_bop!(i8x16[i8; 16] | u8x16_lt[i8x16_lt_u_test]:
    5586               ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -12, 13, 14, 15],
    5587                [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5588               [0, -1, 0, -1 ,0, -1, 0, 0, 0, -1, 0, -1 ,0, -1, 0, 0]);
    5589    test_bop!(i16x8[i16; 8] | i16x8_lt[i16x8_lt_s_test]:
    5590               ([0, 1, 2, 3, 4, 5, 6, -7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5591               [0, -1, 0, -1 ,0, -1, 0, -1]);
    5592    test_bop!(i16x8[i16; 8] | u16x8_lt[i16x8_lt_u_test]:
    5593               ([0, 1, 2, 3, 4, 5, 6, -7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5594               [0, -1, 0, -1 ,0, -1, 0, 0]);
    5595    test_bop!(i32x4[i32; 4] | i32x4_lt[i32x4_lt_s_test]:
    5596               ([-1, 1, 2, 3], [0, 2, 2, 4]) => [-1, -1, 0, -1]);
    5597    test_bop!(i32x4[i32; 4] | u32x4_lt[i32x4_lt_u_test]:
    5598               ([-1, 1, 2, 3], [0, 2, 2, 4]) => [0, -1, 0, -1]);
    5599    test_bop!(i64x2[i64; 2] | i64x2_lt[i64x2_lt_s_test]:
    5600               ([-1, 3], [0, 2]) => [-1, 0]);
    5601    test_bop!(f32x4[f32; 4] => i32 | f32x4_lt[f32x4_lt_test]:
    5602               ([0., 1., 2., 3.], [0., 2., 2., 4.]) => [0, -1, 0, -1]);
    5603    test_bop!(f64x2[f64; 2] => i64 | f64x2_lt[f64x2_lt_test]: ([0., 1.], [0., 2.]) => [0, -1]);
    5604
    5605    test_bop!(i8x16[i8; 16] | i8x16_gt[i8x16_gt_s_test]:
    5606           ([0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, -15],
    5607            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) =>
    5608               [0, -1, 0, -1 ,0, -1, 0, 0, 0, -1, 0, -1 ,0, -1, 0, 0]);
    5609    test_bop!(i8x16[i8; 16] | u8x16_gt[i8x16_gt_u_test]:
    5610           ([0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, -15],
    5611            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) =>
    5612               [0, -1, 0, -1 ,0, -1, 0, 0, 0, -1, 0, -1 ,0, -1, 0, -1]);
    5613    test_bop!(i16x8[i16; 8] | i16x8_gt[i16x8_gt_s_test]:
    5614               ([0, 2, 2, 4, 4, 6, 6, -7], [0, 1, 2, 3, 4, 5, 6, 7]) =>
    5615               [0, -1, 0, -1 ,0, -1, 0, 0]);
    5616    test_bop!(i16x8[i16; 8] | u16x8_gt[i16x8_gt_u_test]:
    5617               ([0, 2, 2, 4, 4, 6, 6, -7], [0, 1, 2, 3, 4, 5, 6, 7]) =>
    5618               [0, -1, 0, -1 ,0, -1, 0, -1]);
    5619    test_bop!(i32x4[i32; 4] | i32x4_gt[i32x4_gt_s_test]:
    5620               ([0, 2, 2, -4], [0, 1, 2, 3]) => [0, -1, 0, 0]);
    5621    test_bop!(i32x4[i32; 4] | u32x4_gt[i32x4_gt_u_test]:
    5622               ([0, 2, 2, -4], [0, 1, 2, 3]) => [0, -1, 0, -1]);
    5623    test_bop!(i64x2[i64; 2] | i64x2_gt[i64x2_gt_s_test]:
    5624               ([-1, 2], [0, 1]) => [0, -1]);
    5625    test_bop!(f32x4[f32; 4] => i32 | f32x4_gt[f32x4_gt_test]:
    5626               ([0., 2., 2., 4.], [0., 1., 2., 3.]) => [0, -1, 0, -1]);
    5627    test_bop!(f64x2[f64; 2] => i64 | f64x2_gt[f64x2_gt_test]: ([0., 2.], [0., 1.]) => [0, -1]);
    5628
    5629    test_bop!(i8x16[i8; 16] | i8x16_ge[i8x16_ge_s_test]:
    5630               ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -15],
    5631                [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5632               [-1, 0, -1, 0 ,-1, 0, -1, -1, -1, 0, -1, 0 ,-1, 0, -1, 0]);
    5633    test_bop!(i8x16[i8; 16] | u8x16_ge[i8x16_ge_u_test]:
    5634               ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -15],
    5635                [0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, 15]) =>
    5636               [-1, 0, -1, 0 ,-1, 0, -1, -1, -1, 0, -1, 0 ,-1, 0, -1, -1]);
    5637    test_bop!(i16x8[i16; 8] | i16x8_ge[i16x8_ge_s_test]:
    5638               ([0, 1, 2, 3, 4, 5, 6, -7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5639               [-1, 0, -1, 0 ,-1, 0, -1, 0]);
    5640    test_bop!(i16x8[i16; 8] | u16x8_ge[i16x8_ge_u_test]:
    5641               ([0, 1, 2, 3, 4, 5, 6, -7], [0, 2, 2, 4, 4, 6, 6, 7]) =>
    5642               [-1, 0, -1, 0 ,-1, 0, -1, -1]);
    5643    test_bop!(i32x4[i32; 4] | i32x4_ge[i32x4_ge_s_test]:
    5644               ([0, 1, 2, -3], [0, 2, 2, 4]) => [-1, 0, -1, 0]);
    5645    test_bop!(i32x4[i32; 4] | u32x4_ge[i32x4_ge_u_test]:
    5646               ([0, 1, 2, -3], [0, 2, 2, 4]) => [-1, 0, -1, -1]);
    5647    test_bop!(i64x2[i64; 2] | i64x2_ge[i64x2_ge_s_test]:
    5648               ([0, 1], [-1, 2]) => [-1, 0]);
    5649    test_bop!(f32x4[f32; 4] => i32 | f32x4_ge[f32x4_ge_test]:
    5650               ([0., 1., 2., 3.], [0., 2., 2., 4.]) => [-1, 0, -1, 0]);
    5651    test_bop!(f64x2[f64; 2] => i64 | f64x2_ge[f64x2_ge_test]: ([0., 1.], [0., 2.]) => [-1, 0]);
    5652
    5653    test_bop!(i8x16[i8; 16] | i8x16_le[i8x16_le_s_test]:
    5654               ([0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, -15],
    5655                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    5656               ) =>
    5657               [-1, 0, -1, 0 ,-1, 0, -1, -1, -1, 0, -1, 0 ,-1, 0, -1, -1]);
    5658    test_bop!(i8x16[i8; 16] | u8x16_le[i8x16_le_u_test]:
    5659               ([0, 2, 2, 4, 4, 6, 6, 7, 8, 10, 10, 12, 12, 14, 14, -15],
    5660                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    5661               ) =>
    5662               [-1, 0, -1, 0 ,-1, 0, -1, -1, -1, 0, -1, 0 ,-1, 0, -1, 0]);
    5663    test_bop!(i16x8[i16; 8] | i16x8_le[i16x8_le_s_test]:
    5664               ([0, 2, 2, 4, 4, 6, 6, -7], [0, 1, 2, 3, 4, 5, 6, 7]) =>
    5665               [-1, 0, -1, 0 ,-1, 0, -1, -1]);
    5666    test_bop!(i16x8[i16; 8] | u16x8_le[i16x8_le_u_test]:
    5667               ([0, 2, 2, 4, 4, 6, 6, -7], [0, 1, 2, 3, 4, 5, 6, 7]) =>
    5668               [-1, 0, -1, 0 ,-1, 0, -1, 0]);
    5669    test_bop!(i32x4[i32; 4] | i32x4_le[i32x4_le_s_test]:
    5670               ([0, 2, 2, -4], [0, 1, 2, 3]) => [-1, 0, -1, -1]);
    5671    test_bop!(i32x4[i32; 4] | u32x4_le[i32x4_le_u_test]:
    5672               ([0, 2, 2, -4], [0, 1, 2, 3]) => [-1, 0, -1, 0]);
    5673    test_bop!(i64x2[i64; 2] | i64x2_le[i64x2_le_s_test]:
    5674               ([0, 2], [0, 1]) => [-1, 0]);
    5675    test_bop!(f32x4[f32; 4] => i32 | f32x4_le[f32x4_le_test]:
    5676               ([0., 2., 2., 4.], [0., 1., 2., 3.]) => [-1, 0, -1, -0]);
    5677    test_bop!(f64x2[f64; 2] => i64 | f64x2_le[f64x2_le_test]: ([0., 2.], [0., 1.]) => [-1, 0]);
    5678
    5679    test_uop!(f32x4[f32; 4] | f32x4_neg[f32x4_neg_test]: [0., 1., 2., 3.] => [ 0., -1., -2., -3.]);
    5680    test_uop!(f32x4[f32; 4] | f32x4_abs[f32x4_abs_test]: [0., -1., 2., -3.] => [ 0., 1., 2., 3.]);
    5681    test_bop!(f32x4[f32; 4] | f32x4_min[f32x4_min_test]:
    5682              ([0., -1., 7., 8.], [1., -3., -4., 10.]) => [0., -3., -4., 8.]);
    5683    test_bop!(f32x4[f32; 4] | f32x4_min[f32x4_min_test_nan]:
    5684              ([0., -1., 7., 8.], [1., -3., -4., f32::NAN])
    5685              => [0., -3., -4., f32::NAN]);
    5686    test_bop!(f32x4[f32; 4] | f32x4_max[f32x4_max_test]:
    5687              ([0., -1., 7., 8.], [1., -3., -4., 10.]) => [1., -1., 7., 10.]);
    5688    test_bop!(f32x4[f32; 4] | f32x4_max[f32x4_max_test_nan]:
    5689              ([0., -1., 7., 8.], [1., -3., -4., f32::NAN])
    5690              => [1., -1., 7., f32::NAN]);
    5691    test_bop!(f32x4[f32; 4] | f32x4_add[f32x4_add_test]:
    5692              ([0., -1., 7., 8.], [1., -3., -4., 10.]) => [1., -4., 3., 18.]);
    5693    test_bop!(f32x4[f32; 4] | f32x4_sub[f32x4_sub_test]:
    5694              ([0., -1., 7., 8.], [1., -3., -4., 10.]) => [-1., 2., 11., -2.]);
    5695    test_bop!(f32x4[f32; 4] | f32x4_mul[f32x4_mul_test]:
    5696              ([0., -1., 7., 8.], [1., -3., -4., 10.]) => [0., 3., -28., 80.]);
    5697    test_bop!(f32x4[f32; 4] | f32x4_div[f32x4_div_test]:
    5698              ([0., -8., 70., 8.], [1., 4., 10., 2.]) => [0., -2., 7., 4.]);
    5699
    5700    test_uop!(f64x2[f64; 2] | f64x2_neg[f64x2_neg_test]: [0., 1.] => [ 0., -1.]);
    5701    test_uop!(f64x2[f64; 2] | f64x2_abs[f64x2_abs_test]: [0., -1.] => [ 0., 1.]);
    5702    test_bop!(f64x2[f64; 2] | f64x2_min[f64x2_min_test]:
    5703               ([0., -1.], [1., -3.]) => [0., -3.]);
    5704    test_bop!(f64x2[f64; 2] | f64x2_min[f64x2_min_test_nan]:
    5705               ([7., 8.], [-4., f64::NAN])
    5706               => [ -4., f64::NAN]);
    5707    test_bop!(f64x2[f64; 2] | f64x2_max[f64x2_max_test]:
    5708               ([0., -1.], [1., -3.]) => [1., -1.]);
    5709    test_bop!(f64x2[f64; 2] | f64x2_max[f64x2_max_test_nan]:
    5710               ([7., 8.], [ -4., f64::NAN])
    5711               => [7., f64::NAN]);
    5712    test_bop!(f64x2[f64; 2] | f64x2_add[f64x2_add_test]:
    5713               ([0., -1.], [1., -3.]) => [1., -4.]);
    5714    test_bop!(f64x2[f64; 2] | f64x2_sub[f64x2_sub_test]:
    5715               ([0., -1.], [1., -3.]) => [-1., 2.]);
    5716    test_bop!(f64x2[f64; 2] | f64x2_mul[f64x2_mul_test]:
    5717               ([0., -1.], [1., -3.]) => [0., 3.]);
    5718    test_bop!(f64x2[f64; 2] | f64x2_div[f64x2_div_test]:
    5719               ([0., -8.], [1., 4.]) => [0., -2.]);
    5720
    5721    macro_rules! test_conv {
    5722        ($test_id:ident | $conv_id:ident | $to_ty:ident | $from:expr,  $to:expr) => {
    5723            #[test]
    5724            fn $test_id() {
    5725                unsafe {
    5726                    let from: v128 = transmute($from);
    5727                    let to: v128 = transmute($to);
    5728
    5729                    let r: v128 = $conv_id(from);
    5730
    5731                    compare_bytes(r, to);
    5732                }
    5733            }
    5734        };
    5735    }
    5736
    5737    test_conv!(
    5738        f32x4_convert_s_i32x4 | f32x4_convert_i32x4 | f32x4 | [1_i32, 2, 3, 4],
    5739        [1_f32, 2., 3., 4.]
    5740    );
    5741    test_conv!(
    5742        f32x4_convert_u_i32x4 | f32x4_convert_u32x4 | f32x4 | [u32::MAX, 2, 3, 4],
    5743        [u32::MAX as f32, 2., 3., 4.]
    5744    );
    5745
    5746    #[test]
    5747    fn test_conversions() {
    5748        compare_bytes(
    5749            i32x4_trunc_sat_f32x4(f32x4(1., f32::NEG_INFINITY, f32::INFINITY, f32::NAN)),
    5750            i32x4(1, i32::MIN, i32::MAX, 0),
    5751        );
    5752        compare_bytes(
    5753            u32x4_trunc_sat_f32x4(f32x4(1., f32::NEG_INFINITY, f32::INFINITY, f32::NAN)),
    5754            u32x4(1, 0, u32::MAX, 0),
    5755        );
    5756        compare_bytes(f64x2_convert_low_i32x4(i32x4(1, 2, 3, 4)), f64x2(1., 2.));
    5757        compare_bytes(
    5758            f64x2_convert_low_i32x4(i32x4(i32::MIN, i32::MAX, 3, 4)),
    5759            f64x2(f64::from(i32::MIN), f64::from(i32::MAX)),
    5760        );
    5761        compare_bytes(f64x2_convert_low_u32x4(u32x4(1, 2, 3, 4)), f64x2(1., 2.));
    5762        compare_bytes(
    5763            f64x2_convert_low_u32x4(u32x4(u32::MIN, u32::MAX, 3, 4)),
    5764            f64x2(f64::from(u32::MIN), f64::from(u32::MAX)),
    5765        );
    5766
    5767        compare_bytes(
    5768            i32x4_trunc_sat_f64x2_zero(f64x2(1., f64::NEG_INFINITY)),
    5769            i32x4(1, i32::MIN, 0, 0),
    5770        );
    5771        compare_bytes(
    5772            i32x4_trunc_sat_f64x2_zero(f64x2(f64::NAN, f64::INFINITY)),
    5773            i32x4(0, i32::MAX, 0, 0),
    5774        );
    5775        compare_bytes(
    5776            u32x4_trunc_sat_f64x2_zero(f64x2(1., f64::NEG_INFINITY)),
    5777            u32x4(1, 0, 0, 0),
    5778        );
    5779        compare_bytes(
    5780            u32x4_trunc_sat_f64x2_zero(f64x2(f64::NAN, f64::INFINITY)),
    5781            u32x4(0, u32::MAX, 0, 0),
    5782        );
    5783    }
    5784
    5785    #[test]
    5786    fn test_popcnt() {
    5787        unsafe {
    5788            for i in 0..=255 {
    5789                compare_bytes(
    5790                    i8x16_popcnt(u8x16_splat(i)),
    5791                    u8x16_splat(i.count_ones() as u8),
    5792                )
    5793            }
    5794
    5795            let vectors = [
    5796                [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    5797                [
    5798                    100, 200, 50, 0, 10, 7, 38, 185, 192, 3, 34, 85, 93, 7, 31, 99,
    5799                ],
    5800            ];
    5801
    5802            for vector in vectors.iter() {
    5803                compare_bytes(
    5804                    i8x16_popcnt(transmute(*vector)),
    5805                    i8x16(
    5806                        vector[0].count_ones() as i8,
    5807                        vector[1].count_ones() as i8,
    5808                        vector[2].count_ones() as i8,
    5809                        vector[3].count_ones() as i8,
    5810                        vector[4].count_ones() as i8,
    5811                        vector[5].count_ones() as i8,
    5812                        vector[6].count_ones() as i8,
    5813                        vector[7].count_ones() as i8,
    5814                        vector[8].count_ones() as i8,
    5815                        vector[9].count_ones() as i8,
    5816                        vector[10].count_ones() as i8,
    5817                        vector[11].count_ones() as i8,
    5818                        vector[12].count_ones() as i8,
    5819                        vector[13].count_ones() as i8,
    5820                        vector[14].count_ones() as i8,
    5821                        vector[15].count_ones() as i8,
    5822                    ),
    5823                )
    5824            }
    5825        }
    5826    }
    5827
    5828    #[test]
    5829    fn test_promote_demote() {
    5830        let tests = [
    5831            [1., 2.],
    5832            [f64::NAN, f64::INFINITY],
    5833            [100., 201.],
    5834            [0., -0.],
    5835            [f64::NEG_INFINITY, 0.],
    5836        ];
    5837
    5838        for [a, b] in tests {
    5839            compare_bytes(
    5840                f32x4_demote_f64x2_zero(f64x2(a, b)),
    5841                f32x4(a as f32, b as f32, 0., 0.),
    5842            );
    5843            compare_bytes(
    5844                f64x2_promote_low_f32x4(f32x4(a as f32, b as f32, 0., 0.)),
    5845                f64x2(a, b),
    5846            );
    5847        }
    5848    }
    5849
    5850    #[test]
    5851    fn test_extmul() {
    5852        macro_rules! test {
    5853            ($(
    5854                $ctor:ident {
    5855                    from: $from:ident,
    5856                    to: $to:ident,
    5857                    low: $low:ident,
    5858                    high: $high:ident,
    5859                } => {
    5860                    $(([$($a:tt)*] * [$($b:tt)*]))*
    5861                }
    5862            )*) => ($(
    5863                $(unsafe {
    5864                    let a: [$from; 16 / mem::size_of::<$from>()] = [$($a)*];
    5865                    let b: [$from; 16 / mem::size_of::<$from>()] = [$($b)*];
    5866                    let low = mem::transmute::<_, [$to; 16 / mem::size_of::<$to>()]>($low($ctor($($a)*), $ctor($($b)*)));
    5867                    let high = mem::transmute::<_, [$to; 16 / mem::size_of::<$to>()]>($high($ctor($($a)*), $ctor($($b)*)));
    5868
    5869                    let half = a.len() / 2;
    5870                    for i in 0..half {
    5871                        assert_eq!(
    5872                            (a[i] as $to).wrapping_mul((b[i] as $to)),
    5873                            low[i],
    5874                            "expected {} * {}", a[i] as $to, b[i] as $to,
    5875                        );
    5876                        assert_eq!(
    5877                            (a[half + i] as $to).wrapping_mul((b[half + i] as $to)),
    5878                            high[i],
    5879                            "expected {} * {}", a[half + i] as $to, b[half + i] as $to,
    5880                        );
    5881                    }
    5882                })*
    5883            )*)
    5884        }
    5885        test! {
    5886            i8x16 {
    5887                from: i8,
    5888                to: i16,
    5889                low: i16x8_extmul_low_i8x16,
    5890                high: i16x8_extmul_high_i8x16,
    5891            } => {
    5892                (
    5893                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    5894                        *
    5895                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    5896                )
    5897                (
    5898                    [-1, -2, 3, 100, 124, -38, 33, 87, 92, 108, 22, 8, -43, -128, 22, 0]
    5899                        *
    5900                    [-5, -2, 6, 10, 45, -4, 4, -2, 0, 88, 92, -102, -98, 83, 73, 54]
    5901                )
    5902            }
    5903            u8x16 {
    5904                from: u8,
    5905                to: u16,
    5906                low: u16x8_extmul_low_u8x16,
    5907                high: u16x8_extmul_high_u8x16,
    5908            } => {
    5909                (
    5910                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    5911                        *
    5912                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    5913                )
    5914                (
    5915                    [1, 2, 3, 100, 124, 38, 33, 87, 92, 198, 22, 8, 43, 128, 22, 0]
    5916                        *
    5917                    [5, 200, 6, 10, 45, 248, 4, 2, 0, 2, 92, 102, 234, 83, 73, 54]
    5918                )
    5919            }
    5920            i16x8 {
    5921                from: i16,
    5922                to: i32,
    5923                low: i32x4_extmul_low_i16x8,
    5924                high: i32x4_extmul_high_i16x8,
    5925            } => {
    5926                (
    5927                    [0, 0, 0, 0, 0, 0, 0, 0]
    5928                        *
    5929                    [0, 0, 0, 0, 0, 0, 0, 0]
    5930                )
    5931                (
    5932                    [-1, 0, i16::MAX, 19931, -2259, 64, 200, 87]
    5933                        *
    5934                    [1, 1, i16::MIN, 29391, 105, 2, 100, -2]
    5935                )
    5936            }
    5937            u16x8 {
    5938                from: u16,
    5939                to: u32,
    5940                low: u32x4_extmul_low_u16x8,
    5941                high: u32x4_extmul_high_u16x8,
    5942            } => {
    5943                (
    5944                    [0, 0, 0, 0, 0, 0, 0, 0]
    5945                        *
    5946                    [0, 0, 0, 0, 0, 0, 0, 0]
    5947                )
    5948                (
    5949                    [1, 0, u16::MAX, 19931, 2259, 64, 200, 87]
    5950                        *
    5951                    [1, 1, 3, 29391, 105, 2, 100, 2]
    5952                )
    5953            }
    5954            i32x4 {
    5955                from: i32,
    5956                to: i64,
    5957                low: i64x2_extmul_low_i32x4,
    5958                high: i64x2_extmul_high_i32x4,
    5959            } => {
    5960                (
    5961                    [0, 0, 0, 0]
    5962                        *
    5963                    [0, 0, 0, 0]
    5964                )
    5965                (
    5966                    [-1, 0, i32::MAX, 19931]
    5967                        *
    5968                    [1, 1, i32::MIN, 29391]
    5969                )
    5970                (
    5971                    [i32::MAX, 3003183, 3 << 20, 0xffffff]
    5972                        *
    5973                    [i32::MAX, i32::MIN, -40042, 300]
    5974                )
    5975            }
    5976            u32x4 {
    5977                from: u32,
    5978                to: u64,
    5979                low: u64x2_extmul_low_u32x4,
    5980                high: u64x2_extmul_high_u32x4,
    5981            } => {
    5982                (
    5983                    [0, 0, 0, 0]
    5984                        *
    5985                    [0, 0, 0, 0]
    5986                )
    5987                (
    5988                    [1, 0, u32::MAX, 19931]
    5989                        *
    5990                    [1, 1, 3, 29391]
    5991                )
    5992                (
    5993                    [u32::MAX, 3003183, 3 << 20, 0xffffff]
    5994                        *
    5995                    [u32::MAX, 3000, 40042, 300]
    5996                )
    5997            }
    5998        }
    5999    }
    6000
    6001    #[test]
    6002    fn test_q15mulr_sat_s() {
    6003        fn test(a: [i16; 8], b: [i16; 8]) {
    6004            let a_v = i16x8(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
    6005            let b_v = i16x8(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
    6006            let result = i16x8_q15mulr_sat(a_v, b_v);
    6007            let result = unsafe { mem::transmute::<v128, [i16; 8]>(result) };
    6008
    6009            for (i, (a, b)) in a.iter().zip(&b).enumerate() {
    6010                assert_eq!(
    6011                    result[i],
    6012                    (((*a as i32) * (*b as i32) + 0x4000) >> 15) as i16
    6013                );
    6014            }
    6015        }
    6016
    6017        test([0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]);
    6018        test([1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]);
    6019        test(
    6020            [-1, 100, 2003, -29494, 12, 128, 994, 1],
    6021            [-4049, 8494, -10483, 0, 5, 2222, 883, -9],
    6022        );
    6023    }
    6024
    6025    #[test]
    6026    fn test_extadd() {
    6027        macro_rules! test {
    6028            ($(
    6029                $func:ident {
    6030                    from: $from:ident,
    6031                    to: $to:ident,
    6032                } => {
    6033                    $([$($a:tt)*])*
    6034                }
    6035            )*) => ($(
    6036                $(unsafe {
    6037                    let a: [$from; 16 / mem::size_of::<$from>()] = [$($a)*];
    6038                    let a_v = mem::transmute::<_, v128>(a);
    6039                    let r = mem::transmute::<v128, [$to; 16 / mem::size_of::<$to>()]>($func(a_v));
    6040
    6041                    let half = a.len() / 2;
    6042                    for i in 0..half {
    6043                        assert_eq!(
    6044                            (a[2 * i] as $to).wrapping_add((a[2 * i + 1] as $to)),
    6045                            r[i],
    6046                            "failed {} + {} != {}",
    6047                            a[2 * i] as $to,
    6048                            a[2 * i + 1] as $to,
    6049                            r[i],
    6050                        );
    6051                    }
    6052                })*
    6053            )*)
    6054        }
    6055        test! {
    6056            i16x8_extadd_pairwise_i8x16 {
    6057                from: i8,
    6058                to: i16,
    6059            } => {
    6060                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    6061                [-1, -2, 3, 100, 124, -38, 33, 87, 92, 108, 22, 8, -43, -128, 22, 0]
    6062                [-5, -2, 6, 10, 45, -4, 4, -2, 0, 88, 92, -102, -98, 83, 73, 54]
    6063            }
    6064            i16x8_extadd_pairwise_u8x16 {
    6065                from: u8,
    6066                to: i16,
    6067            } => {
    6068                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    6069                [1, 2, 3, 100, 124, 38, 33, 87, 92, 198, 22, 8, 43, 128, 22, 0]
    6070                [5, 200, 6, 10, 45, 248, 4, 2, 0, 2, 92, 102, 234, 83, 73, 54]
    6071            }
    6072            i32x4_extadd_pairwise_i16x8 {
    6073                from: i16,
    6074                to: i32,
    6075            } => {
    6076                [0, 0, 0, 0, 0, 0, 0, 0]
    6077                [-1, 0, i16::MAX, 19931, -2259, 64, 200, 87]
    6078                [1, 1, i16::MIN, 29391, 105, 2, 100, -2]
    6079            }
    6080            i32x4_extadd_pairwise_u16x8 {
    6081                from: u16,
    6082                to: i32,
    6083            } => {
    6084                [0, 0, 0, 0, 0, 0, 0, 0]
    6085                [1, 0, u16::MAX, 19931, 2259, 64, 200, 87]
    6086                [1, 1, 3, 29391, 105, 2, 100, 2]
    6087            }
    6088        }
    6089    }
    6090}