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

#
core/stdarch/crates/core_arch/src/x86_64/
sse.rs

    1//! `x86_64` Streaming SIMD Extensions (SSE)
    2
    3use crate::core_arch::x86::*;
    4
    5#[cfg(test)]
    6use stdarch_test::assert_instr;
    7
    8#[allow(improper_ctypes)]
    9unsafe extern "C" {
    10    #[link_name = "llvm.x86.sse.cvtss2si64"]
    11    fn cvtss2si64(a: __m128) -> i64;
    12    #[link_name = "llvm.x86.sse.cvttss2si64"]
    13    fn cvttss2si64(a: __m128) -> i64;
    14}
    15
    16/// Converts the lowest 32 bit float in the input vector to a 64 bit integer.
    17///
    18/// The result is rounded according to the current rounding mode. If the result
    19/// cannot be represented as a 64 bit integer the result will be
    20/// `0x8000_0000_0000_0000` (`i64::MIN`) or trigger an invalid operation
    21/// floating point exception if unmasked (see
    22/// [`_mm_setcsr`](fn._mm_setcsr.html)).
    23///
    24/// This corresponds to the `CVTSS2SI` instruction (with 64 bit output).
    25///
    26/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtss_si64)
    27#[inline]
    28#[target_feature(enable = "sse")]
    29#[cfg_attr(test, assert_instr(cvtss2si))]
    30#[stable(feature = "simd_x86", since = "1.27.0")]
    31pub fn _mm_cvtss_si64(a: __m128) -> i64 {
    32    unsafe { cvtss2si64(a) }
    33}
    34
    35/// Converts the lowest 32 bit float in the input vector to a 64 bit integer
    36/// with truncation.
    37///
    38/// The result is rounded always using truncation (round towards zero). If the
    39/// result cannot be represented as a 64 bit integer the result will be
    40/// `0x8000_0000_0000_0000` (`i64::MIN`) or an invalid operation floating
    41/// point exception if unmasked (see [`_mm_setcsr`](fn._mm_setcsr.html)).
    42///
    43/// This corresponds to the `CVTTSS2SI` instruction (with 64 bit output).
    44///
    45/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvttss_si64)
    46#[inline]
    47#[target_feature(enable = "sse")]
    48#[cfg_attr(test, assert_instr(cvttss2si))]
    49#[stable(feature = "simd_x86", since = "1.27.0")]
    50pub fn _mm_cvttss_si64(a: __m128) -> i64 {
    51    unsafe { cvttss2si64(a) }
    52}
    53
    54/// Converts a 64 bit integer to a 32 bit float. The result vector is the input
    55/// vector `a` with the lowest 32 bit float replaced by the converted integer.
    56///
    57/// This intrinsic corresponds to the `CVTSI2SS` instruction (with 64 bit
    58/// input).
    59///
    60/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi64_ss)
    61#[inline]
    62#[target_feature(enable = "sse")]
    63#[cfg_attr(test, assert_instr(cvtsi2ss))]
    64#[stable(feature = "simd_x86", since = "1.27.0")]
    65#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
    66pub const fn _mm_cvtsi64_ss(a: __m128, b: i64) -> __m128 {
    67    unsafe { simd_insert!(a, 0, b as f32) }
    68}
    69
    70#[cfg(test)]
    71mod tests {
    72    use crate::core_arch::arch::x86_64::*;
    73    use crate::core_arch::assert_eq_const as assert_eq;
    74    use stdarch_test::simd_test;
    75
    76    #[simd_test(enable = "sse")]
    77    fn test_mm_cvtss_si64() {
    78        let inputs = &[
    79            (42.0f32, 42i64),
    80            (-31.4, -31),
    81            (-33.5, -34),
    82            (-34.5, -34),
    83            (4.0e10, 40_000_000_000),
    84            (4.0e-10, 0),
    85            (f32::NAN, i64::MIN),
    86            (2147483500.1, 2147483520),
    87            (9.223371e18, 9223370937343148032),
    88        ];
    89        for (i, &(xi, e)) in inputs.iter().enumerate() {
    90            let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
    91            let r = _mm_cvtss_si64(x);
    92            assert_eq!(
    93                e, r,
    94                "TestCase #{} _mm_cvtss_si64({:?}) = {}, expected: {}",
    95                i, x, r, e
    96            );
    97        }
    98    }
    99
    100    #[simd_test(enable = "sse")]
    101    fn test_mm_cvttss_si64() {
    102        let inputs = &[
    103            (42.0f32, 42i64),
    104            (-31.4, -31),
    105            (-33.5, -33),
    106            (-34.5, -34),
    107            (10.999, 10),
    108            (-5.99, -5),
    109            (4.0e10, 40_000_000_000),
    110            (4.0e-10, 0),
    111            (f32::NAN, i64::MIN),
    112            (2147483500.1, 2147483520),
    113            (9.223371e18, 9223370937343148032),
    114            (9.223372e18, i64::MIN),
    115        ];
    116        for (i, &(xi, e)) in inputs.iter().enumerate() {
    117            let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
    118            let r = _mm_cvttss_si64(x);
    119            assert_eq!(
    120                e, r,
    121                "TestCase #{} _mm_cvttss_si64({:?}) = {}, expected: {}",
    122                i, x, r, e
    123            );
    124        }
    125    }
    126
    127    #[simd_test(enable = "sse")]
    128    const fn test_mm_cvtsi64_ss() {
    129        let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0);
    130
    131        let r = _mm_cvtsi64_ss(a, 4555);
    132        let e = _mm_setr_ps(4555.0, 6.0, 7.0, 8.0);
    133        assert_eq_m128(e, r);
    134
    135        let r = _mm_cvtsi64_ss(a, 322223333);
    136        let e = _mm_setr_ps(322223333.0, 6.0, 7.0, 8.0);
    137        assert_eq_m128(e, r);
    138
    139        let r = _mm_cvtsi64_ss(a, -432);
    140        let e = _mm_setr_ps(-432.0, 6.0, 7.0, 8.0);
    141        assert_eq_m128(e, r);
    142
    143        let r = _mm_cvtsi64_ss(a, -322223333);
    144        let e = _mm_setr_ps(-322223333.0, 6.0, 7.0, 8.0);
    145        assert_eq_m128(e, r);
    146
    147        let r = _mm_cvtsi64_ss(a, 9223372036854775807);
    148        let e = _mm_setr_ps(9.223372e18, 6.0, 7.0, 8.0);
    149        assert_eq_m128(e, r);
    150
    151        let r = _mm_cvtsi64_ss(a, -9223372036854775808);
    152        let e = _mm_setr_ps(-9.223372e18, 6.0, 7.0, 8.0);
    153        assert_eq_m128(e, r);
    154    }
    155}