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