@@ -28,6 +28,11 @@ unsafe extern "unadjusted" {
2828///
2929/// If `length == 0 && index > 0` or `length + index > 64` the result is
3030/// undefined.
31+ ///
32+ /// The extracted bits are saved in the least-significant bit positions of the lower
33+ /// quadword of the destination; the remaining bits in the lower quadword of the
34+ /// destination register are cleared to 0. The upper quadword of the destination
35+ /// register is undefined.
3136#[ inline]
3237#[ target_feature( enable = "sse4a" ) ]
3338#[ cfg_attr( test, assert_instr( extrq) ) ]
@@ -43,7 +48,10 @@ pub fn _mm_extract_si64(x: __m128i, y: __m128i) -> __m128i {
4348/// and index are both zero, bits `[63:0]` of parameter `x` are extracted. It is a compile-time error
4449/// for `len + idx` to be greater than 64 or for `len` to be zero and `idx` to be non-zero.
4550///
46- /// Returns a 128-bit integer vector whose lower 64 bits contain the extracted bits.
51+ /// The extracted bits are saved in the least-significant bit positions of the lower
52+ /// quadword of the destination; the remaining bits in the lower quadword of the
53+ /// destination register are cleared to 0. The upper quadword of the destination
54+ /// register is undefined.
4755#[ inline]
4856#[ target_feature( enable = "sse4a" ) ]
4957#[ cfg_attr( test, assert_instr( extrq, LEN = 5 , IDX = 5 ) ) ]
@@ -66,6 +74,8 @@ pub fn _mm_extracti_si64<const LEN: i32, const IDX: i32>(x: __m128i) -> __m128i
6674///
6775/// If the `length` is zero it is interpreted as `64`. If `index + length > 64`
6876/// or `index > 0 && length == 0` the result is undefined.
77+ ///
78+ /// The upper 64 bits of the destination are undefined.
6979#[ inline]
7080#[ target_feature( enable = "sse4a" ) ]
7181#[ cfg_attr( test, assert_instr( insertq) ) ]
@@ -80,6 +90,8 @@ pub fn _mm_insert_si64(x: __m128i, y: __m128i) -> __m128i {
8090/// `idx` specifies the index of the LSB. `len` specifies the number of bits to insert. If length and index
8191/// are both zero, bits `[63:0]` of parameter `x` are replaced with bits `[63:0]` of parameter `y`. It is a
8292/// compile-time error for `len + idx` to be greater than 64 or for `len` to be zero and `idx` to be non-zero.
93+ ///
94+ /// The upper 64 bits of the destination are undefined.
8395#[ inline]
8496#[ target_feature( enable = "sse4a" ) ]
8597#[ cfg_attr( test, assert_instr( insertq, LEN = 5 , IDX = 5 ) ) ]
@@ -150,6 +162,11 @@ mod tests {
150162 use crate :: core_arch:: x86:: * ;
151163 use stdarch_test:: simd_test;
152164
165+ // Normally this requires SSE2, but for tests it does not matter whether we use the instruction.
166+ fn _mm_cvtsi128_si64 ( a : __m128i ) -> i64 {
167+ unsafe { simd_extract ! ( a. as_i64x2( ) , 0 ) }
168+ }
169+
153170 #[ simd_test( enable = "sse4a" ) ]
154171 fn test_mm_extract_si64 ( ) {
155172 let b = 0b0110_0000_0000_i64 ;
@@ -160,15 +177,23 @@ mod tests {
160177 let y = _mm_setr_epi64x ( v, 0 ) ;
161178 let e = _mm_setr_epi64x ( 0b0110_i64 , 0 ) ;
162179 let r = _mm_extract_si64 ( x, y) ;
163- assert_eq_m128i ( r, e) ;
180+
181+ // The upper quadword of the destination register is undefined.
182+ let r = _mm_cvtsi128_si64 ( r) ;
183+ let e = _mm_cvtsi128_si64 ( e) ;
184+ assert_eq ! ( r, e) ;
164185 }
165186
166187 #[ simd_test( enable = "sse4a" ) ]
167188 fn test_mm_extracti_si64 ( ) {
168189 let a = _mm_setr_epi64x ( 0x0123456789abcdef , 0 ) ;
169190 let r = _mm_extracti_si64 :: < 8 , 8 > ( a) ;
170191 let e = _mm_setr_epi64x ( 0xcd , 0 ) ;
171- assert_eq_m128i ( r, e) ;
192+
193+ // The upper quadword of the destination register is undefined.
194+ let r = _mm_cvtsi128_si64 ( r) ;
195+ let e = _mm_cvtsi128_si64 ( e) ;
196+ assert_eq ! ( r, e) ;
172197 }
173198
174199 #[ simd_test( enable = "sse4a" ) ]
@@ -185,7 +210,11 @@ mod tests {
185210 // ^idx: 2^3 = 8 ^length = 2^2 = 4
186211 let y = _mm_setr_epi64x ( i, v) ;
187212 let r = _mm_insert_si64 ( x, y) ;
188- assert_eq_m128i ( r, expected) ;
213+
214+ // The upper quadword of the destination register is undefined.
215+ let r = _mm_cvtsi128_si64 ( r) ;
216+ let expected = _mm_cvtsi128_si64 ( expected) ;
217+ assert_eq ! ( r, expected) ;
189218 }
190219
191220 #[ simd_test( enable = "sse4a" ) ]
@@ -194,7 +223,11 @@ mod tests {
194223 let b = _mm_setr_epi64x ( 0x0011223344556677 , 0 ) ;
195224 let r = _mm_inserti_si64 :: < 8 , 8 > ( a, b) ;
196225 let e = _mm_setr_epi64x ( 0x0123456789ab77ef , 0 ) ;
197- assert_eq_m128i ( r, e) ;
226+
227+ // The upper quadword of the destination register is undefined.
228+ let r = _mm_cvtsi128_si64 ( r) ;
229+ let e = _mm_cvtsi128_si64 ( e) ;
230+ assert_eq ! ( r, e) ;
198231 }
199232
200233 #[ repr( align( 16 ) ) ]
0 commit comments