diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 5d12bfadcf845..5dc86a679d827 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -599,6 +599,7 @@ extern "rust-intrinsic" { /// # Safety /// /// `idx` must be in-bounds of the vector. + #[rustc_nounwind] pub fn simd_insert(x: T, idx: u32, val: U) -> T; /// Extract an element from a vector. @@ -608,21 +609,25 @@ extern "rust-intrinsic" { /// # Safety /// /// `idx` must be in-bounds of the vector. + #[rustc_nounwind] pub fn simd_extract(x: T, idx: u32) -> U; /// Add two simd vectors elementwise. /// /// `T` must be a vector of integer or floating point primitive types. + #[rustc_nounwind] pub fn simd_add(x: T, y: T) -> T; /// Subtract `rhs` from `lhs` elementwise. /// /// `T` must be a vector of integer or floating point primitive types. + #[rustc_nounwind] pub fn simd_sub(lhs: T, rhs: T) -> T; /// Multiply two simd vectors elementwise. /// /// `T` must be a vector of integer or floating point primitive types. + #[rustc_nounwind] pub fn simd_mul(x: T, y: T) -> T; /// Divide `lhs` by `rhs` elementwise. @@ -632,6 +637,7 @@ extern "rust-intrinsic" { /// # Safety /// For integers, `rhs` must not contain any zero elements. /// Additionally for signed integers, `::MIN / -1` is undefined behavior. + #[rustc_nounwind] pub fn simd_div(lhs: T, rhs: T) -> T; /// Remainder of two vectors elementwise @@ -641,6 +647,7 @@ extern "rust-intrinsic" { /// # Safety /// For integers, `rhs` must not contain any zero elements. /// Additionally for signed integers, `::MIN / -1` is undefined behavior. + #[rustc_nounwind] pub fn simd_rem(lhs: T, rhs: T) -> T; /// Elementwise vector left shift, with UB on overflow. @@ -652,6 +659,7 @@ extern "rust-intrinsic" { /// # Safety /// /// Each element of `rhs` must be less than `::BITS`. + #[rustc_nounwind] pub fn simd_shl(lhs: T, rhs: T) -> T; /// Elementwise vector right shift, with UB on overflow. @@ -663,21 +671,25 @@ extern "rust-intrinsic" { /// # Safety /// /// Each element of `rhs` must be less than `::BITS`. + #[rustc_nounwind] pub fn simd_shr(lhs: T, rhs: T) -> T; /// Elementwise vector "and". /// /// `T` must be a vector of integer primitive types. + #[rustc_nounwind] pub fn simd_and(x: T, y: T) -> T; /// Elementwise vector "or". /// /// `T` must be a vector of integer primitive types. + #[rustc_nounwind] pub fn simd_or(x: T, y: T) -> T; /// Elementwise vector "exclusive or". /// /// `T` must be a vector of integer primitive types. + #[rustc_nounwind] pub fn simd_xor(x: T, y: T) -> T; /// Numerically cast a vector, elementwise. @@ -698,6 +710,7 @@ extern "rust-intrinsic" { /// * Not be `NaN` /// * Not be infinite /// * Be representable in the return type, after truncating off its fractional part + #[rustc_nounwind] pub fn simd_cast(x: T) -> U; /// Numerically cast a vector, elementwise. @@ -711,6 +724,7 @@ extern "rust-intrinsic" { /// When casting floats to integers, the result is truncated. /// When casting integers to floats, the result is rounded. /// Otherwise, truncates or extends the value, maintaining the sign for signed integers. + #[rustc_nounwind] pub fn simd_as(x: T) -> U; /// Elementwise negation of a vector. @@ -718,11 +732,13 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// Rust panics for `-::Min` due to overflow, but it is not UB with this intrinsic. + #[rustc_nounwind] pub fn simd_neg(x: T) -> T; /// Elementwise absolute value of a vector. /// /// `T` must be a vector of floating-point primitive types. + #[rustc_nounwind] pub fn simd_fabs(x: T) -> T; /// Elementwise minimum of a vector. @@ -730,6 +746,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of floating-point primitive types. /// /// Follows IEEE-754 `minNum` semantics. + #[rustc_nounwind] pub fn simd_fmin(x: T, y: T) -> T; /// Elementwise maximum of a vector. @@ -737,6 +754,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of floating-point primitive types. /// /// Follows IEEE-754 `maxNum` semantics. + #[rustc_nounwind] pub fn simd_fmax(x: T, y: T) -> T; /// Tests elementwise equality of two vectors. @@ -746,6 +764,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_eq(x: T, y: T) -> U; /// Tests elementwise inequality equality of two vectors. @@ -755,6 +774,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_ne(x: T, y: T) -> U; /// Tests if `x` is less than `y`, elementwise. @@ -764,6 +784,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_lt(x: T, y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. @@ -773,6 +794,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_le(x: T, y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. @@ -782,6 +804,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_gt(x: T, y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. @@ -791,6 +814,7 @@ extern "rust-intrinsic" { /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// /// Returns `0` for false and `!0` for true. + #[rustc_nounwind] pub fn simd_ge(x: T, y: T) -> U; /// Shuffle two vectors by const indices. @@ -805,6 +829,7 @@ extern "rust-intrinsic" { /// Returns a new vector such that element `i` is selected from `xy[idx[i]]`, where `xy` /// is the concatenation of `x` and `y`. It is a compile-time error if `idx[i]` is out-of-bounds /// of `xy`. + #[rustc_nounwind] pub fn simd_shuffle(x: T, y: T, idx: U) -> V; /// Shuffle two vectors by const indices. @@ -816,6 +841,7 @@ extern "rust-intrinsic" { /// Returns a new vector such that element `i` is selected from `xy[IDX[i]]`, where `xy` /// is the concatenation of `x` and `y`. It is a compile-time error if `IDX[i]` is out-of-bounds /// of `xy`. + #[rustc_nounwind] pub fn simd_shuffle_generic(x: T, y: T) -> U; /// Read a vector of pointers. @@ -838,6 +864,7 @@ extern "rust-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. + #[rustc_nounwind] pub fn simd_gather(val: T, ptr: U, mask: V) -> T; /// Write to a vector of pointers. @@ -860,6 +887,7 @@ extern "rust-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. + #[rustc_nounwind] pub fn simd_scatter(val: T, ptr: U, mask: V); /// Read a vector of pointers. @@ -881,6 +909,7 @@ extern "rust-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. + #[rustc_nounwind] pub fn simd_masked_load(mask: V, ptr: U, val: T) -> T; /// Write to a vector of pointers. @@ -901,11 +930,13 @@ extern "rust-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. + #[rustc_nounwind] pub fn simd_masked_store(mask: V, ptr: U, val: T); /// Add two simd vectors elementwise, with saturation. /// /// `T` must be a vector of integer primitive types. + #[rustc_nounwind] pub fn simd_saturating_add(x: T, y: T) -> T; /// Subtract two simd vectors elementwise, with saturation. @@ -913,6 +944,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer primitive types. /// /// Subtract `rhs` from `lhs`. + #[rustc_nounwind] pub fn simd_saturating_sub(lhs: T, rhs: T) -> T; /// Add elements within a vector from left to right. @@ -922,6 +954,7 @@ extern "rust-intrinsic" { /// `U` must be the element type of `T`. /// /// Starting with the value `y`, add the elements of `x` and accumulate. + #[rustc_nounwind] pub fn simd_reduce_add_ordered(x: T, y: U) -> U; /// Add elements within a vector in arbitrary order. May also be re-associated with @@ -930,6 +963,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be the element type of `T`. + #[rustc_nounwind] pub fn simd_reduce_add_unordered(x: T) -> U; /// Multiply elements within a vector from left to right. @@ -939,6 +973,7 @@ extern "rust-intrinsic" { /// `U` must be the element type of `T`. /// /// Starting with the value `y`, multiply the elements of `x` and accumulate. + #[rustc_nounwind] pub fn simd_reduce_mul_ordered(x: T, y: U) -> U; /// Add elements within a vector in arbitrary order. May also be re-associated with @@ -947,6 +982,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be the element type of `T`. + #[rustc_nounwind] pub fn simd_reduce_mul_unordered(x: T) -> U; /// Check if all mask values are true. @@ -955,6 +991,7 @@ extern "rust-intrinsic" { /// /// # Safety /// `x` must contain only `0` or `!0`. + #[rustc_nounwind] pub fn simd_reduce_all(x: T) -> bool; /// Check if all mask values are true. @@ -963,6 +1000,7 @@ extern "rust-intrinsic" { /// /// # Safety /// `x` must contain only `0` or `!0`. + #[rustc_nounwind] pub fn simd_reduce_any(x: T) -> bool; /// Return the maximum element of a vector. @@ -972,6 +1010,7 @@ extern "rust-intrinsic" { /// `U` must be the element type of `T`. /// /// For floating-point values, uses IEEE-754 `maxNum`. + #[rustc_nounwind] pub fn simd_reduce_max(x: T) -> U; /// Return the minimum element of a vector. @@ -981,6 +1020,7 @@ extern "rust-intrinsic" { /// `U` must be the element type of `T`. /// /// For floating-point values, uses IEEE-754 `minNum`. + #[rustc_nounwind] pub fn simd_reduce_min(x: T) -> U; /// Logical "and" all elements together. @@ -988,6 +1028,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be the element type of `T`. + #[rustc_nounwind] pub fn simd_reduce_and(x: T) -> U; /// Logical "or" all elements together. @@ -995,6 +1036,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be the element type of `T`. + #[rustc_nounwind] pub fn simd_reduce_or(x: T) -> U; /// Logical "exclusive or" all elements together. @@ -1002,6 +1044,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be the element type of `T`. + #[rustc_nounwind] pub fn simd_reduce_xor(x: T) -> U; /// Truncate an integer vector to a bitmask. @@ -1030,6 +1073,7 @@ extern "rust-intrinsic" { /// /// # Safety /// `x` must contain only `0` and `!0`. + #[rustc_nounwind] pub fn simd_bitmask(x: T) -> U; /// Select elements from a mask. @@ -1044,6 +1088,7 @@ extern "rust-intrinsic" { /// /// # Safety /// `mask` must only contain `0` and `!0`. + #[rustc_nounwind] pub fn simd_select(mask: M, if_true: T, if_false: T) -> T; /// Select elements from a bitmask. @@ -1060,6 +1105,7 @@ extern "rust-intrinsic" { /// /// # Safety /// Padding bits must be all zero. + #[rustc_nounwind] pub fn simd_select_bitmask(m: M, yes: T, no: T) -> T; /// Elementwise calculates the offset from a pointer vector, potentially wrapping. @@ -1069,11 +1115,13 @@ extern "rust-intrinsic" { /// `U` must be a vector of `isize` or `usize` with the same number of elements as `T`. /// /// Operates as if by `::wrapping_offset`. + #[rustc_nounwind] pub fn simd_arith_offset(ptr: T, offset: U) -> T; /// Cast a vector of pointers. /// /// `T` and `U` must be vectors of pointers with the same number of elements. + #[rustc_nounwind] pub fn simd_cast_ptr(ptr: T) -> U; /// Expose a vector of pointers as a vector of addresses. @@ -1081,6 +1129,7 @@ extern "rust-intrinsic" { /// `T` must be a vector of pointers. /// /// `U` must be a vector of `usize` with the same length as `T`. + #[rustc_nounwind] pub fn simd_expose_addr(ptr: T) -> U; /// Create a vector of pointers from a vector of addresses. @@ -1088,92 +1137,110 @@ extern "rust-intrinsic" { /// `T` must be a vector of `usize`. /// /// `U` must be a vector of pointers, with the same length as `T`. + #[rustc_nounwind] pub fn simd_from_exposed_addr(addr: T) -> U; /// Swap bytes of each element. /// /// `T` must be a vector of integers. + #[rustc_nounwind] pub fn simd_bswap(x: T) -> T; /// Reverse bits of each element. /// /// `T` must be a vector of integers. + #[rustc_nounwind] pub fn simd_bitreverse(x: T) -> T; /// Count the leading zeros of each element. /// /// `T` must be a vector of integers. + #[rustc_nounwind] pub fn simd_ctlz(x: T) -> T; /// Count the trailing zeros of each element. /// /// `T` must be a vector of integers. + #[rustc_nounwind] pub fn simd_cttz(x: T) -> T; /// Round up each element to the next highest integer-valued float. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_ceil(x: T) -> T; /// Round down each element to the next lowest integer-valued float. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_floor(x: T) -> T; /// Round each element to the closest integer-valued float. /// Ties are resolved by rounding away from 0. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_round(x: T) -> T; /// Return the integer part of each element as an integer-valued float. /// In other words, non-integer values are truncated towards zero. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_trunc(x: T) -> T; /// Takes the square root of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fsqrt(x: T) -> T; /// Computes `(x*y) + z` for each element, but without any intermediate rounding. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fma(x: T, y: T, z: T) -> T; // Computes the sine of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fsin(a: T) -> T; // Computes the cosine of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fcos(a: T) -> T; // Computes the exponential function of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fexp(a: T) -> T; // Computes 2 raised to the power of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_fexp2(a: T) -> T; // Computes the base 10 logarithm of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_flog10(a: T) -> T; // Computes the base 2 logarithm of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_flog2(a: T) -> T; // Computes the natural logarithm of each element. /// /// `T` must be a vector of floats. + #[rustc_nounwind] pub fn simd_flog(a: T) -> T; }