]> git.proxmox.com Git - rustc.git/blob - src/stdsimd/crates/core_arch/src/x86/mmx.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / stdsimd / crates / core_arch / src / x86 / mmx.rs
1 //! `i586` MMX instruction set.
2 //!
3 //! The intrinsics here roughly correspond to those in the `mmintrin.h` C
4 //! header.
5 //!
6 //! The reference is [Intel 64 and IA-32 Architectures Software Developer's
7 //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref].
8 //!
9 //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
10
11 use core_arch::simd::*;
12 use core_arch::x86::*;
13 use mem;
14
15 #[cfg(test)]
16 use stdsimd_test::assert_instr;
17
18 /// Constructs a 64-bit integer vector initialized to zero.
19 #[inline]
20 #[target_feature(enable = "mmx")]
21 // FIXME: this produces a movl instead of xorps on x86
22 // FIXME: this produces a xor intrinsic instead of xorps on x86_64
23 #[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(xor))]
24 pub unsafe fn _mm_setzero_si64() -> __m64 {
25 mem::transmute(0_i64)
26 }
27
28 /// Add packed 8-bit integers in `a` and `b`.
29 #[inline]
30 #[target_feature(enable = "mmx")]
31 #[cfg_attr(test, assert_instr(paddb))]
32 pub unsafe fn _mm_add_pi8(a: __m64, b: __m64) -> __m64 {
33 paddb(a, b)
34 }
35
36 /// Add packed 8-bit integers in `a` and `b`.
37 #[inline]
38 #[target_feature(enable = "mmx")]
39 #[cfg_attr(test, assert_instr(paddb))]
40 pub unsafe fn _m_paddb(a: __m64, b: __m64) -> __m64 {
41 _mm_add_pi8(a, b)
42 }
43
44 /// Add packed 16-bit integers in `a` and `b`.
45 #[inline]
46 #[target_feature(enable = "mmx")]
47 #[cfg_attr(test, assert_instr(paddw))]
48 pub unsafe fn _mm_add_pi16(a: __m64, b: __m64) -> __m64 {
49 paddw(a, b)
50 }
51
52 /// Add packed 16-bit integers in `a` and `b`.
53 #[inline]
54 #[target_feature(enable = "mmx")]
55 #[cfg_attr(test, assert_instr(paddw))]
56 pub unsafe fn _m_paddw(a: __m64, b: __m64) -> __m64 {
57 _mm_add_pi16(a, b)
58 }
59
60 /// Add packed 32-bit integers in `a` and `b`.
61 #[inline]
62 #[target_feature(enable = "mmx")]
63 #[cfg_attr(test, assert_instr(paddd))]
64 pub unsafe fn _mm_add_pi32(a: __m64, b: __m64) -> __m64 {
65 paddd(a, b)
66 }
67
68 /// Add packed 32-bit integers in `a` and `b`.
69 #[inline]
70 #[target_feature(enable = "mmx")]
71 #[cfg_attr(test, assert_instr(paddd))]
72 pub unsafe fn _m_paddd(a: __m64, b: __m64) -> __m64 {
73 _mm_add_pi32(a, b)
74 }
75
76 /// Add packed 8-bit integers in `a` and `b` using saturation.
77 #[inline]
78 #[target_feature(enable = "mmx")]
79 #[cfg_attr(test, assert_instr(paddsb))]
80 pub unsafe fn _mm_adds_pi8(a: __m64, b: __m64) -> __m64 {
81 paddsb(a, b)
82 }
83
84 /// Add packed 8-bit integers in `a` and `b` using saturation.
85 #[inline]
86 #[target_feature(enable = "mmx")]
87 #[cfg_attr(test, assert_instr(paddsb))]
88 pub unsafe fn _m_paddsb(a: __m64, b: __m64) -> __m64 {
89 _mm_adds_pi8(a, b)
90 }
91
92 /// Add packed 16-bit integers in `a` and `b` using saturation.
93 #[inline]
94 #[target_feature(enable = "mmx")]
95 #[cfg_attr(test, assert_instr(paddsw))]
96 pub unsafe fn _mm_adds_pi16(a: __m64, b: __m64) -> __m64 {
97 paddsw(a, b)
98 }
99
100 /// Add packed 16-bit integers in `a` and `b` using saturation.
101 #[inline]
102 #[target_feature(enable = "mmx")]
103 #[cfg_attr(test, assert_instr(paddsw))]
104 pub unsafe fn _m_paddsw(a: __m64, b: __m64) -> __m64 {
105 _mm_adds_pi16(a, b)
106 }
107
108 /// Add packed unsigned 8-bit integers in `a` and `b` using saturation.
109 #[inline]
110 #[target_feature(enable = "mmx")]
111 #[cfg_attr(test, assert_instr(paddusb))]
112 pub unsafe fn _mm_adds_pu8(a: __m64, b: __m64) -> __m64 {
113 paddusb(a, b)
114 }
115
116 /// Add packed unsigned 8-bit integers in `a` and `b` using saturation.
117 #[inline]
118 #[target_feature(enable = "mmx")]
119 #[cfg_attr(test, assert_instr(paddusb))]
120 pub unsafe fn _m_paddusb(a: __m64, b: __m64) -> __m64 {
121 _mm_adds_pu8(a, b)
122 }
123
124 /// Add packed unsigned 16-bit integers in `a` and `b` using saturation.
125 #[inline]
126 #[target_feature(enable = "mmx")]
127 #[cfg_attr(test, assert_instr(paddusw))]
128 pub unsafe fn _mm_adds_pu16(a: __m64, b: __m64) -> __m64 {
129 paddusw(a, b)
130 }
131
132 /// Add packed unsigned 16-bit integers in `a` and `b` using saturation.
133 #[inline]
134 #[target_feature(enable = "mmx")]
135 #[cfg_attr(test, assert_instr(paddusw))]
136 pub unsafe fn _m_paddusw(a: __m64, b: __m64) -> __m64 {
137 _mm_adds_pu16(a, b)
138 }
139
140 /// Subtract packed 8-bit integers in `b` from packed 8-bit integers in `a`.
141 #[inline]
142 #[target_feature(enable = "mmx")]
143 #[cfg_attr(test, assert_instr(psubb))]
144 pub unsafe fn _mm_sub_pi8(a: __m64, b: __m64) -> __m64 {
145 psubb(a, b)
146 }
147
148 /// Subtract packed 8-bit integers in `b` from packed 8-bit integers in `a`.
149 #[inline]
150 #[target_feature(enable = "mmx")]
151 #[cfg_attr(test, assert_instr(psubb))]
152 pub unsafe fn _m_psubb(a: __m64, b: __m64) -> __m64 {
153 _mm_sub_pi8(a, b)
154 }
155
156 /// Subtract packed 16-bit integers in `b` from packed 16-bit integers in `a`.
157 #[inline]
158 #[target_feature(enable = "mmx")]
159 #[cfg_attr(test, assert_instr(psubw))]
160 pub unsafe fn _mm_sub_pi16(a: __m64, b: __m64) -> __m64 {
161 psubw(a, b)
162 }
163
164 /// Subtract packed 16-bit integers in `b` from packed 16-bit integers in `a`.
165 #[inline]
166 #[target_feature(enable = "mmx")]
167 #[cfg_attr(test, assert_instr(psubw))]
168 pub unsafe fn _m_psubw(a: __m64, b: __m64) -> __m64 {
169 _mm_sub_pi16(a, b)
170 }
171
172 /// Subtract packed 32-bit integers in `b` from packed 32-bit integers in `a`.
173 #[inline]
174 #[target_feature(enable = "mmx")]
175 #[cfg_attr(test, assert_instr(psubd))]
176 pub unsafe fn _mm_sub_pi32(a: __m64, b: __m64) -> __m64 {
177 psubd(a, b)
178 }
179
180 /// Subtract packed 32-bit integers in `b` from packed 32-bit integers in `a`.
181 #[inline]
182 #[target_feature(enable = "mmx")]
183 #[cfg_attr(test, assert_instr(psubd))]
184 pub unsafe fn _m_psubd(a: __m64, b: __m64) -> __m64 {
185 _mm_sub_pi32(a, b)
186 }
187
188 /// Subtract packed 8-bit integers in `b` from packed 8-bit integers in `a`
189 /// using saturation.
190 #[inline]
191 #[target_feature(enable = "mmx")]
192 #[cfg_attr(test, assert_instr(psubsb))]
193 pub unsafe fn _mm_subs_pi8(a: __m64, b: __m64) -> __m64 {
194 psubsb(a, b)
195 }
196
197 /// Subtract packed 8-bit integers in `b` from packed 8-bit integers in `a`
198 /// using saturation.
199 #[inline]
200 #[target_feature(enable = "mmx")]
201 #[cfg_attr(test, assert_instr(psubsb))]
202 pub unsafe fn _m_psubsb(a: __m64, b: __m64) -> __m64 {
203 _mm_subs_pi8(a, b)
204 }
205
206 /// Subtract packed 16-bit integers in `b` from packed 16-bit integers in `a`
207 /// using saturation.
208 #[inline]
209 #[target_feature(enable = "mmx")]
210 #[cfg_attr(test, assert_instr(psubsw))]
211 pub unsafe fn _mm_subs_pi16(a: __m64, b: __m64) -> __m64 {
212 psubsw(a, b)
213 }
214
215 /// Subtract packed 16-bit integers in `b` from packed 16-bit integers in `a`
216 /// using saturation.
217 #[inline]
218 #[target_feature(enable = "mmx")]
219 #[cfg_attr(test, assert_instr(psubsw))]
220 pub unsafe fn _m_psubsw(a: __m64, b: __m64) -> __m64 {
221 _mm_subs_pi16(a, b)
222 }
223
224 /// Subtract packed unsigned 8-bit integers in `b` from packed unsigned 8-bit
225 /// integers in `a` using saturation.
226 #[inline]
227 #[target_feature(enable = "mmx")]
228 #[cfg_attr(test, assert_instr(psubusb))]
229 pub unsafe fn _mm_subs_pu8(a: __m64, b: __m64) -> __m64 {
230 psubusb(a, b)
231 }
232
233 /// Subtract packed unsigned 8-bit integers in `b` from packed unsigned 8-bit
234 /// integers in `a` using saturation.
235 #[inline]
236 #[target_feature(enable = "mmx")]
237 #[cfg_attr(test, assert_instr(psubusb))]
238 pub unsafe fn _m_psubusb(a: __m64, b: __m64) -> __m64 {
239 _mm_subs_pu8(a, b)
240 }
241
242 /// Subtract packed unsigned 16-bit integers in `b` from packed unsigned
243 /// 16-bit integers in `a` using saturation.
244 #[inline]
245 #[target_feature(enable = "mmx")]
246 #[cfg_attr(test, assert_instr(psubusw))]
247 pub unsafe fn _mm_subs_pu16(a: __m64, b: __m64) -> __m64 {
248 psubusw(a, b)
249 }
250
251 /// Subtract packed unsigned 16-bit integers in `b` from packed unsigned
252 /// 16-bit integers in `a` using saturation.
253 #[inline]
254 #[target_feature(enable = "mmx")]
255 #[cfg_attr(test, assert_instr(psubusw))]
256 pub unsafe fn _m_psubusw(a: __m64, b: __m64) -> __m64 {
257 _mm_subs_pu16(a, b)
258 }
259
260 /// Convert packed 16-bit integers from `a` and `b` to packed 8-bit integers
261 /// using signed saturation.
262 ///
263 /// Positive values greater than 0x7F are saturated to 0x7F. Negative values
264 /// less than 0x80 are saturated to 0x80.
265 #[inline]
266 #[target_feature(enable = "mmx")]
267 #[cfg_attr(test, assert_instr(packsswb))]
268 pub unsafe fn _mm_packs_pi16(a: __m64, b: __m64) -> __m64 {
269 packsswb(a, b)
270 }
271
272 /// Convert packed 32-bit integers from `a` and `b` to packed 16-bit integers
273 /// using signed saturation.
274 ///
275 /// Positive values greater than 0x7F are saturated to 0x7F. Negative values
276 /// less than 0x80 are saturated to 0x80.
277 #[inline]
278 #[target_feature(enable = "mmx")]
279 #[cfg_attr(test, assert_instr(packssdw))]
280 pub unsafe fn _mm_packs_pi32(a: __m64, b: __m64) -> __m64 {
281 packssdw(a, b)
282 }
283
284 /// Compares whether each element of `a` is greater than the corresponding
285 /// element of `b` returning `0` for `false` and `-1` for `true`.
286 #[inline]
287 #[target_feature(enable = "mmx")]
288 #[cfg_attr(test, assert_instr(pcmpgtb))]
289 pub unsafe fn _mm_cmpgt_pi8(a: __m64, b: __m64) -> __m64 {
290 pcmpgtb(a, b)
291 }
292
293 /// Compares whether each element of `a` is greater than the corresponding
294 /// element of `b` returning `0` for `false` and `-1` for `true`.
295 #[inline]
296 #[target_feature(enable = "mmx")]
297 #[cfg_attr(test, assert_instr(pcmpgtw))]
298 pub unsafe fn _mm_cmpgt_pi16(a: __m64, b: __m64) -> __m64 {
299 pcmpgtw(a, b)
300 }
301
302 /// Compares whether each element of `a` is greater than the corresponding
303 /// element of `b` returning `0` for `false` and `-1` for `true`.
304 #[inline]
305 #[target_feature(enable = "mmx")]
306 #[cfg_attr(test, assert_instr(pcmpgtd))]
307 pub unsafe fn _mm_cmpgt_pi32(a: __m64, b: __m64) -> __m64 {
308 pcmpgtd(a, b)
309 }
310
311 /// Unpacks the upper two elements from two `i16x4` vectors and interleaves
312 /// them into the result: `[a.2, b.2, a.3, b.3]`.
313 #[inline]
314 #[target_feature(enable = "mmx")]
315 #[cfg_attr(test, assert_instr(punpckhwd))] // FIXME punpcklbw expected
316 pub unsafe fn _mm_unpackhi_pi16(a: __m64, b: __m64) -> __m64 {
317 punpckhwd(a, b)
318 }
319
320 /// Unpacks the upper four elements from two `i8x8` vectors and interleaves
321 /// them into the result: `[a.4, b.4, a.5, b.5, a.6, b.6, a.7, b.7]`.
322 #[inline]
323 #[target_feature(enable = "mmx")]
324 #[cfg_attr(test, assert_instr(punpckhbw))]
325 pub unsafe fn _mm_unpackhi_pi8(a: __m64, b: __m64) -> __m64 {
326 punpckhbw(a, b)
327 }
328
329 /// Unpacks the lower four elements from two `i8x8` vectors and interleaves
330 /// them into the result: `[a.0, b.0, a.1, b.1, a.2, b.2, a.3, b.3]`.
331 #[inline]
332 #[target_feature(enable = "mmx")]
333 #[cfg_attr(test, assert_instr(punpcklbw))]
334 pub unsafe fn _mm_unpacklo_pi8(a: __m64, b: __m64) -> __m64 {
335 punpcklbw(a, b)
336 }
337
338 /// Unpacks the lower two elements from two `i16x4` vectors and interleaves
339 /// them into the result: `[a.0 b.0 a.1 b.1]`.
340 #[inline]
341 #[target_feature(enable = "mmx")]
342 #[cfg_attr(test, assert_instr(punpcklwd))]
343 pub unsafe fn _mm_unpacklo_pi16(a: __m64, b: __m64) -> __m64 {
344 punpcklwd(a, b)
345 }
346
347 /// Unpacks the upper element from two `i32x2` vectors and interleaves them
348 /// into the result: `[a.1, b.1]`.
349 #[inline]
350 #[target_feature(enable = "mmx")]
351 #[cfg_attr(test, assert_instr(punpckhdq))]
352 pub unsafe fn _mm_unpackhi_pi32(a: __m64, b: __m64) -> __m64 {
353 punpckhdq(a, b)
354 }
355
356 /// Unpacks the lower element from two `i32x2` vectors and interleaves them
357 /// into the result: `[a.0, b.0]`.
358 #[inline]
359 #[target_feature(enable = "mmx")]
360 #[cfg_attr(test, assert_instr(punpckldq))]
361 pub unsafe fn _mm_unpacklo_pi32(a: __m64, b: __m64) -> __m64 {
362 punpckldq(a, b)
363 }
364
365 /// Set packed 16-bit integers in dst with the supplied values.
366 #[inline]
367 #[target_feature(enable = "mmx")]
368 pub unsafe fn _mm_set_pi16(e3: i16, e2: i16, e1: i16, e0: i16) -> __m64 {
369 _mm_setr_pi16(e0, e1, e2, e3)
370 }
371
372 /// Set packed 32-bit integers in dst with the supplied values.
373 #[inline]
374 #[target_feature(enable = "mmx")]
375 pub unsafe fn _mm_set_pi32(e1: i32, e0: i32) -> __m64 {
376 _mm_setr_pi32(e0, e1)
377 }
378
379 /// Set packed 8-bit integers in dst with the supplied values.
380 #[inline]
381 #[target_feature(enable = "mmx")]
382 pub unsafe fn _mm_set_pi8(e7: i8, e6: i8, e5: i8, e4: i8, e3: i8, e2: i8, e1: i8, e0: i8) -> __m64 {
383 _mm_setr_pi8(e0, e1, e2, e3, e4, e5, e6, e7)
384 }
385
386 /// Broadcast 16-bit integer a to all all elements of dst.
387 #[inline]
388 #[target_feature(enable = "mmx")]
389 pub unsafe fn _mm_set1_pi16(a: i16) -> __m64 {
390 _mm_setr_pi16(a, a, a, a)
391 }
392
393 /// Broadcast 32-bit integer a to all all elements of dst.
394 #[inline]
395 #[target_feature(enable = "mmx")]
396 pub unsafe fn _mm_set1_pi32(a: i32) -> __m64 {
397 _mm_setr_pi32(a, a)
398 }
399
400 /// Broadcast 8-bit integer a to all all elements of dst.
401 #[inline]
402 #[target_feature(enable = "mmx")]
403 pub unsafe fn _mm_set1_pi8(a: i8) -> __m64 {
404 _mm_setr_pi8(a, a, a, a, a, a, a, a)
405 }
406
407 /// Set packed 16-bit integers in dst with the supplied values in reverse
408 /// order.
409 #[inline]
410 #[target_feature(enable = "mmx")]
411 pub unsafe fn _mm_setr_pi16(e0: i16, e1: i16, e2: i16, e3: i16) -> __m64 {
412 mem::transmute(i16x4::new(e0, e1, e2, e3))
413 }
414
415 /// Set packed 32-bit integers in dst with the supplied values in reverse
416 /// order.
417 #[inline]
418 #[target_feature(enable = "mmx")]
419 pub unsafe fn _mm_setr_pi32(e0: i32, e1: i32) -> __m64 {
420 mem::transmute(i32x2::new(e0, e1))
421 }
422
423 /// Set packed 8-bit integers in dst with the supplied values in reverse order.
424 #[inline]
425 #[target_feature(enable = "mmx")]
426 pub unsafe fn _mm_setr_pi8(
427 e0: i8,
428 e1: i8,
429 e2: i8,
430 e3: i8,
431 e4: i8,
432 e5: i8,
433 e6: i8,
434 e7: i8,
435 ) -> __m64 {
436 mem::transmute(i8x8::new(e0, e1, e2, e3, e4, e5, e6, e7))
437 }
438
439 /// Empty the MMX state, which marks the x87 FPU registers as available for use
440 /// by x87 instructions. This instruction must be used at the end of all MMX
441 /// technology procedures.
442 #[inline]
443 #[target_feature(enable = "mmx")]
444 #[cfg_attr(test, assert_instr(emms))]
445 pub unsafe fn _mm_empty() {
446 emms()
447 }
448
449 /// Empty the MMX state, which marks the x87 FPU registers as available for use
450 /// by x87 instructions. This instruction must be used at the end of all MMX
451 /// technology procedures.
452 #[inline]
453 #[target_feature(enable = "mmx")]
454 #[cfg_attr(test, assert_instr(emms))]
455 pub unsafe fn _m_empty() {
456 emms()
457 }
458
459 /// Copy 32-bit integer `a` to the lower elements of the return value, and zero
460 /// the upper element of the return value.
461 #[inline]
462 #[target_feature(enable = "mmx")]
463 pub unsafe fn _mm_cvtsi32_si64(a: i32) -> __m64 {
464 mem::transmute(i32x2::new(a, 0))
465 }
466
467 /// Return the lower 32-bit integer in `a`.
468 #[inline]
469 #[target_feature(enable = "mmx")]
470 pub unsafe fn _mm_cvtsi64_si32(a: __m64) -> i32 {
471 let r: i32x2 = mem::transmute(a);
472 r.0
473 }
474
475 #[allow(improper_ctypes)]
476 extern "C" {
477 #[link_name = "llvm.x86.mmx.padd.b"]
478 fn paddb(a: __m64, b: __m64) -> __m64;
479 #[link_name = "llvm.x86.mmx.padd.w"]
480 fn paddw(a: __m64, b: __m64) -> __m64;
481 #[link_name = "llvm.x86.mmx.padd.d"]
482 fn paddd(a: __m64, b: __m64) -> __m64;
483 #[link_name = "llvm.x86.mmx.padds.b"]
484 fn paddsb(a: __m64, b: __m64) -> __m64;
485 #[link_name = "llvm.x86.mmx.padds.w"]
486 fn paddsw(a: __m64, b: __m64) -> __m64;
487 #[link_name = "llvm.x86.mmx.paddus.b"]
488 fn paddusb(a: __m64, b: __m64) -> __m64;
489 #[link_name = "llvm.x86.mmx.paddus.w"]
490 fn paddusw(a: __m64, b: __m64) -> __m64;
491 #[link_name = "llvm.x86.mmx.psub.b"]
492 fn psubb(a: __m64, b: __m64) -> __m64;
493 #[link_name = "llvm.x86.mmx.psub.w"]
494 fn psubw(a: __m64, b: __m64) -> __m64;
495 #[link_name = "llvm.x86.mmx.psub.d"]
496 fn psubd(a: __m64, b: __m64) -> __m64;
497 #[link_name = "llvm.x86.mmx.psubs.b"]
498 fn psubsb(a: __m64, b: __m64) -> __m64;
499 #[link_name = "llvm.x86.mmx.psubs.w"]
500 fn psubsw(a: __m64, b: __m64) -> __m64;
501 #[link_name = "llvm.x86.mmx.psubus.b"]
502 fn psubusb(a: __m64, b: __m64) -> __m64;
503 #[link_name = "llvm.x86.mmx.psubus.w"]
504 fn psubusw(a: __m64, b: __m64) -> __m64;
505 #[link_name = "llvm.x86.mmx.packsswb"]
506 fn packsswb(a: __m64, b: __m64) -> __m64;
507 #[link_name = "llvm.x86.mmx.packssdw"]
508 fn packssdw(a: __m64, b: __m64) -> __m64;
509 #[link_name = "llvm.x86.mmx.pcmpgt.b"]
510 fn pcmpgtb(a: __m64, b: __m64) -> __m64;
511 #[link_name = "llvm.x86.mmx.pcmpgt.w"]
512 fn pcmpgtw(a: __m64, b: __m64) -> __m64;
513 #[link_name = "llvm.x86.mmx.pcmpgt.d"]
514 fn pcmpgtd(a: __m64, b: __m64) -> __m64;
515 #[link_name = "llvm.x86.mmx.punpckhwd"]
516 fn punpckhwd(a: __m64, b: __m64) -> __m64;
517 #[link_name = "llvm.x86.mmx.punpcklwd"]
518 fn punpcklwd(a: __m64, b: __m64) -> __m64;
519 #[link_name = "llvm.x86.mmx.punpckhbw"]
520 fn punpckhbw(a: __m64, b: __m64) -> __m64;
521 #[link_name = "llvm.x86.mmx.punpcklbw"]
522 fn punpcklbw(a: __m64, b: __m64) -> __m64;
523 #[link_name = "llvm.x86.mmx.punpckhdq"]
524 fn punpckhdq(a: __m64, b: __m64) -> __m64;
525 #[link_name = "llvm.x86.mmx.punpckldq"]
526 fn punpckldq(a: __m64, b: __m64) -> __m64;
527 #[link_name = "llvm.x86.mmx.emms"]
528 fn emms();
529 }
530
531 #[cfg(test)]
532 mod tests {
533 use core_arch::x86::*;
534 use stdsimd_test::simd_test;
535
536 #[simd_test(enable = "mmx")]
537 unsafe fn test_mm_setzero_si64() {
538 let r: __m64 = ::std::mem::transmute(0_i64);
539 assert_eq_m64(r, _mm_setzero_si64());
540 }
541
542 #[simd_test(enable = "mmx")]
543 unsafe fn test_mm_add_pi8() {
544 let a = _mm_setr_pi8(-1, -1, 1, 1, -1, 0, 1, 0);
545 let b = _mm_setr_pi8(-127, 101, 99, 126, 0, -1, 0, 1);
546 let e = _mm_setr_pi8(-128, 100, 100, 127, -1, -1, 1, 1);
547 assert_eq_m64(e, _mm_add_pi8(a, b));
548 assert_eq_m64(e, _m_paddb(a, b));
549 }
550
551 #[simd_test(enable = "mmx")]
552 unsafe fn test_mm_add_pi16() {
553 let a = _mm_setr_pi16(-1, -1, 1, 1);
554 let b = _mm_setr_pi16(i16::min_value() + 1, 30001, -30001, i16::max_value() - 1);
555 let e = _mm_setr_pi16(i16::min_value(), 30000, -30000, i16::max_value());
556 assert_eq_m64(e, _mm_add_pi16(a, b));
557 assert_eq_m64(e, _m_paddw(a, b));
558 }
559
560 #[simd_test(enable = "mmx")]
561 unsafe fn test_mm_add_pi32() {
562 let a = _mm_setr_pi32(1, -1);
563 let b = _mm_setr_pi32(i32::max_value() - 1, i32::min_value() + 1);
564 let e = _mm_setr_pi32(i32::max_value(), i32::min_value());
565 assert_eq_m64(e, _mm_add_pi32(a, b));
566 assert_eq_m64(e, _m_paddd(a, b));
567 }
568
569 #[simd_test(enable = "mmx")]
570 unsafe fn test_mm_adds_pi8() {
571 let a = _mm_setr_pi8(-100, -1, 1, 100, -1, 0, 1, 0);
572 let b = _mm_setr_pi8(-100, 1, -1, 100, 0, -1, 0, 1);
573 let e = _mm_setr_pi8(i8::min_value(), 0, 0, i8::max_value(), -1, -1, 1, 1);
574 assert_eq_m64(e, _mm_adds_pi8(a, b));
575 assert_eq_m64(e, _m_paddsb(a, b));
576 }
577
578 #[simd_test(enable = "mmx")]
579 unsafe fn test_mm_adds_pi16() {
580 let a = _mm_setr_pi16(-32000, 32000, 4, 0);
581 let b = _mm_setr_pi16(-32000, 32000, -5, 1);
582 let e = _mm_setr_pi16(i16::min_value(), i16::max_value(), -1, 1);
583 assert_eq_m64(e, _mm_adds_pi16(a, b));
584 assert_eq_m64(e, _m_paddsw(a, b));
585 }
586
587 #[simd_test(enable = "mmx")]
588 unsafe fn test_mm_adds_pu8() {
589 let a = _mm_setr_pi8(0, 1, 2, 3, 4, 5, 6, 200u8 as i8);
590 let b = _mm_setr_pi8(0, 10, 20, 30, 40, 50, 60, 200u8 as i8);
591 let e = _mm_setr_pi8(0, 11, 22, 33, 44, 55, 66, u8::max_value() as i8);
592 assert_eq_m64(e, _mm_adds_pu8(a, b));
593 assert_eq_m64(e, _m_paddusb(a, b));
594 }
595
596 #[simd_test(enable = "mmx")]
597 unsafe fn test_mm_adds_pu16() {
598 let a = _mm_setr_pi16(0, 1, 2, 60000u16 as i16);
599 let b = _mm_setr_pi16(0, 10, 20, 60000u16 as i16);
600 let e = _mm_setr_pi16(0, 11, 22, u16::max_value() as i16);
601 assert_eq_m64(e, _mm_adds_pu16(a, b));
602 assert_eq_m64(e, _m_paddusw(a, b));
603 }
604
605 #[simd_test(enable = "mmx")]
606 unsafe fn test_mm_sub_pi8() {
607 let a = _mm_setr_pi8(0, 0, 1, 1, -1, -1, 0, 0);
608 let b = _mm_setr_pi8(-1, 1, -2, 2, 100, -100, -127, 127);
609 let e = _mm_setr_pi8(1, -1, 3, -1, -101, 99, 127, -127);
610 assert_eq_m64(e, _mm_sub_pi8(a, b));
611 assert_eq_m64(e, _m_psubb(a, b));
612 }
613
614 #[simd_test(enable = "mmx")]
615 unsafe fn test_mm_sub_pi16() {
616 let a = _mm_setr_pi16(-20000, -20000, 20000, 30000);
617 let b = _mm_setr_pi16(-10000, 10000, -10000, 30000);
618 let e = _mm_setr_pi16(-10000, -30000, 30000, 0);
619 assert_eq_m64(e, _mm_sub_pi16(a, b));
620 assert_eq_m64(e, _m_psubw(a, b));
621 }
622
623 #[simd_test(enable = "mmx")]
624 unsafe fn test_mm_sub_pi32() {
625 let a = _mm_setr_pi32(500_000, -500_000);
626 let b = _mm_setr_pi32(500_000, 500_000);
627 let e = _mm_setr_pi32(0, -1_000_000);
628 assert_eq_m64(e, _mm_sub_pi32(a, b));
629 assert_eq_m64(e, _m_psubd(a, b));
630 }
631
632 #[simd_test(enable = "mmx")]
633 unsafe fn test_mm_subs_pi8() {
634 let a = _mm_setr_pi8(-100, 100, 0, 0, 0, 0, -5, 5);
635 let b = _mm_setr_pi8(100, -100, i8::min_value(), 127, -1, 1, 3, -3);
636 let e = _mm_setr_pi8(
637 i8::min_value(),
638 i8::max_value(),
639 i8::max_value(),
640 -127,
641 1,
642 -1,
643 -8,
644 8,
645 );
646 assert_eq_m64(e, _mm_subs_pi8(a, b));
647 assert_eq_m64(e, _m_psubsb(a, b));
648 }
649
650 #[simd_test(enable = "mmx")]
651 unsafe fn test_mm_subs_pi16() {
652 let a = _mm_setr_pi16(-20000, 20000, 0, 0);
653 let b = _mm_setr_pi16(20000, -20000, -1, 1);
654 let e = _mm_setr_pi16(i16::min_value(), i16::max_value(), 1, -1);
655 assert_eq_m64(e, _mm_subs_pi16(a, b));
656 assert_eq_m64(e, _m_psubsw(a, b));
657 }
658
659 #[simd_test(enable = "mmx")]
660 unsafe fn test_mm_subs_pu8() {
661 let a = _mm_setr_pi8(50, 10, 20, 30, 40, 60, 70, 80);
662 let b = _mm_setr_pi8(60, 20, 30, 40, 30, 20, 10, 0);
663 let e = _mm_setr_pi8(0, 0, 0, 0, 10, 40, 60, 80);
664 assert_eq_m64(e, _mm_subs_pu8(a, b));
665 assert_eq_m64(e, _m_psubusb(a, b));
666 }
667
668 #[simd_test(enable = "mmx")]
669 unsafe fn test_mm_subs_pu16() {
670 let a = _mm_setr_pi16(10000, 200, 0, 44444u16 as i16);
671 let b = _mm_setr_pi16(20000, 300, 1, 11111);
672 let e = _mm_setr_pi16(0, 0, 0, 33333u16 as i16);
673 assert_eq_m64(e, _mm_subs_pu16(a, b));
674 assert_eq_m64(e, _m_psubusw(a, b));
675 }
676
677 #[simd_test(enable = "mmx")]
678 unsafe fn test_mm_packs_pi16() {
679 let a = _mm_setr_pi16(-1, 2, -3, 4);
680 let b = _mm_setr_pi16(-5, 6, -7, 8);
681 let r = _mm_setr_pi8(-1, 2, -3, 4, -5, 6, -7, 8);
682 assert_eq_m64(r, _mm_packs_pi16(a, b));
683 }
684
685 #[simd_test(enable = "mmx")]
686 unsafe fn test_mm_packs_pi32() {
687 let a = _mm_setr_pi32(-1, 2);
688 let b = _mm_setr_pi32(-5, 6);
689 let r = _mm_setr_pi16(-1, 2, -5, 6);
690 assert_eq_m64(r, _mm_packs_pi32(a, b));
691 }
692
693 #[simd_test(enable = "mmx")]
694 unsafe fn test_mm_cmpgt_pi8() {
695 let a = _mm_setr_pi8(0, 1, 2, 3, 4, 5, 6, 7);
696 let b = _mm_setr_pi8(8, 7, 6, 5, 4, 3, 2, 1);
697 let r = _mm_setr_pi8(0, 0, 0, 0, 0, -1, -1, -1);
698 assert_eq_m64(r, _mm_cmpgt_pi8(a, b));
699 }
700
701 #[simd_test(enable = "mmx")]
702 unsafe fn test_mm_cmpgt_pi16() {
703 let a = _mm_setr_pi16(0, 1, 2, 3);
704 let b = _mm_setr_pi16(4, 3, 2, 1);
705 let r = _mm_setr_pi16(0, 0, 0, -1);
706 assert_eq_m64(r, _mm_cmpgt_pi16(a, b));
707 }
708
709 #[simd_test(enable = "mmx")]
710 unsafe fn test_mm_cmpgt_pi32() {
711 let a = _mm_setr_pi32(0, 3);
712 let b = _mm_setr_pi32(1, 2);
713 let r0 = _mm_setr_pi32(0, -1);
714 let r1 = _mm_setr_pi32(-1, 0);
715
716 assert_eq_m64(r0, _mm_cmpgt_pi32(a, b));
717 assert_eq_m64(r1, _mm_cmpgt_pi32(b, a));
718 }
719
720 #[simd_test(enable = "mmx")]
721 unsafe fn test_mm_unpackhi_pi8() {
722 let a = _mm_setr_pi8(0, 3, 4, 7, 8, 11, 12, 15);
723 let b = _mm_setr_pi8(1, 2, 5, 6, 9, 10, 13, 14);
724 let r = _mm_setr_pi8(8, 9, 11, 10, 12, 13, 15, 14);
725
726 assert_eq_m64(r, _mm_unpackhi_pi8(a, b));
727 }
728
729 #[simd_test(enable = "mmx")]
730 unsafe fn test_mm_unpacklo_pi8() {
731 let a = _mm_setr_pi8(0, 1, 2, 3, 4, 5, 6, 7);
732 let b = _mm_setr_pi8(8, 9, 10, 11, 12, 13, 14, 15);
733 let r = _mm_setr_pi8(0, 8, 1, 9, 2, 10, 3, 11);
734 assert_eq_m64(r, _mm_unpacklo_pi8(a, b));
735 }
736
737 #[simd_test(enable = "mmx")]
738 unsafe fn test_mm_unpackhi_pi16() {
739 let a = _mm_setr_pi16(0, 1, 2, 3);
740 let b = _mm_setr_pi16(4, 5, 6, 7);
741 let r = _mm_setr_pi16(2, 6, 3, 7);
742 assert_eq_m64(r, _mm_unpackhi_pi16(a, b));
743 }
744
745 #[simd_test(enable = "mmx")]
746 unsafe fn test_mm_unpacklo_pi16() {
747 let a = _mm_setr_pi16(0, 1, 2, 3);
748 let b = _mm_setr_pi16(4, 5, 6, 7);
749 let r = _mm_setr_pi16(0, 4, 1, 5);
750 assert_eq_m64(r, _mm_unpacklo_pi16(a, b));
751 }
752
753 #[simd_test(enable = "mmx")]
754 unsafe fn test_mm_unpackhi_pi32() {
755 let a = _mm_setr_pi32(0, 3);
756 let b = _mm_setr_pi32(1, 2);
757 let r = _mm_setr_pi32(3, 2);
758
759 assert_eq_m64(r, _mm_unpackhi_pi32(a, b));
760 }
761
762 #[simd_test(enable = "mmx")]
763 unsafe fn test_mm_unpacklo_pi32() {
764 let a = _mm_setr_pi32(0, 3);
765 let b = _mm_setr_pi32(1, 2);
766 let r = _mm_setr_pi32(0, 1);
767
768 assert_eq_m64(r, _mm_unpacklo_pi32(a, b));
769 }
770
771 #[simd_test(enable = "mmx")]
772 unsafe fn test_mm_empty() {
773 _mm_empty();
774 }
775
776 #[simd_test(enable = "mmx")]
777 unsafe fn test_m_empty() {
778 _m_empty();
779 }
780
781 #[simd_test(enable = "mmx")]
782 unsafe fn test_mm_cvtsi32_si64() {
783 let a = _mm_cvtsi32_si64(42);
784 let b = _mm_setr_pi32(42, 0);
785 assert_eq_m64(a, b);
786 }
787
788 #[simd_test(enable = "mmx")]
789 unsafe fn test_mm_cvtsi64_si32() {
790 let a = _mm_setr_pi32(42, 666);
791 let b = _mm_cvtsi64_si32(a);
792 assert_eq!(b, 42);
793 }
794 }