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