]>
git.proxmox.com Git - rustc.git/blob - src/stdsimd/coresimd/arm/neon.rs
1 //! ARMv7 NEON intrinsics
4 use stdsimd_test
::assert_instr
;
6 use coresimd
::simd_llvm
::simd_add
;
8 use convert
::{From, Into}
;
12 #[target_feature(enable = "neon")]
13 #[cfg_attr(test, assert_instr(add))]
14 pub unsafe fn vadd_s8(a
: i8x8
, b
: i8x8
) -> i8x8
{
20 #[target_feature(enable = "neon")]
21 #[cfg_attr(test, assert_instr(add))]
22 pub unsafe fn vaddq_s8(a
: i8x16
, b
: i8x16
) -> i8x16
{
28 #[target_feature(enable = "neon")]
29 #[cfg_attr(test, assert_instr(add))]
30 pub unsafe fn vadd_s16(a
: i16x4
, b
: i16x4
) -> i16x4
{
36 #[target_feature(enable = "neon")]
37 #[cfg_attr(test, assert_instr(add))]
38 pub unsafe fn vaddq_s16(a
: i16x8
, b
: i16x8
) -> i16x8
{
44 #[target_feature(enable = "neon")]
45 #[cfg_attr(test, assert_instr(add))]
46 pub unsafe fn vadd_s32(a
: i32x2
, b
: i32x2
) -> i32x2
{
52 #[target_feature(enable = "neon")]
53 #[cfg_attr(test, assert_instr(add))]
54 pub unsafe fn vaddq_s32(a
: i32x4
, b
: i32x4
) -> i32x4
{
60 #[target_feature(enable = "neon")]
61 #[cfg_attr(test, assert_instr(add))]
62 pub unsafe fn vaddq_s64(a
: i64x2
, b
: i64x2
) -> i64x2
{
68 #[target_feature(enable = "neon")]
69 #[cfg_attr(test, assert_instr(add))]
70 pub unsafe fn vadd_u8(a
: u8x8
, b
: u8x8
) -> u8x8
{
76 #[target_feature(enable = "neon")]
77 #[cfg_attr(test, assert_instr(add))]
78 pub unsafe fn vaddq_u8(a
: u8x16
, b
: u8x16
) -> u8x16
{
84 #[target_feature(enable = "neon")]
85 #[cfg_attr(test, assert_instr(add))]
86 pub unsafe fn vadd_u16(a
: u16x4
, b
: u16x4
) -> u16x4
{
92 #[target_feature(enable = "neon")]
93 #[cfg_attr(test, assert_instr(add))]
94 pub unsafe fn vaddq_u16(a
: u16x8
, b
: u16x8
) -> u16x8
{
100 #[target_feature(enable = "neon")]
101 #[cfg_attr(test, assert_instr(add))]
102 pub unsafe fn vadd_u32(a
: u32x2
, b
: u32x2
) -> u32x2
{
108 #[target_feature(enable = "neon")]
109 #[cfg_attr(test, assert_instr(add))]
110 pub unsafe fn vaddq_u32(a
: u32x4
, b
: u32x4
) -> u32x4
{
116 #[target_feature(enable = "neon")]
117 #[cfg_attr(test, assert_instr(add))]
118 pub unsafe fn vaddq_u64(a
: u64x2
, b
: u64x2
) -> u64x2
{
124 #[target_feature(enable = "neon")]
125 #[cfg_attr(test, assert_instr(fadd))]
126 pub unsafe fn vadd_f32(a
: f32x2
, b
: f32x2
) -> f32x2
{
132 #[target_feature(enable = "neon")]
133 #[cfg_attr(test, assert_instr(fadd))]
134 pub unsafe fn vaddq_f32(a
: f32x4
, b
: f32x4
) -> f32x4
{
140 #[target_feature(enable = "neon")]
141 #[cfg_attr(test, assert_instr(saddl))]
142 pub unsafe fn vaddl_s8(a
: i8x8
, b
: i8x8
) -> i16x8
{
143 let a
= i16x8
::from(a
);
144 let b
= i16x8
::from(b
);
150 #[target_feature(enable = "neon")]
151 #[cfg_attr(test, assert_instr(saddl))]
152 pub unsafe fn vaddl_s16(a
: i16x4
, b
: i16x4
) -> i32x4
{
153 let a
= i32x4
::from(a
);
154 let b
= i32x4
::from(b
);
160 #[target_feature(enable = "neon")]
161 #[cfg_attr(test, assert_instr(saddl))]
162 pub unsafe fn vaddl_s32(a
: i32x2
, b
: i32x2
) -> i64x2
{
163 let a
= i64x2
::from(a
);
164 let b
= i64x2
::from(b
);
170 #[target_feature(enable = "neon")]
171 #[cfg_attr(test, assert_instr(uaddl))]
172 pub unsafe fn vaddl_u8(a
: u8x8
, b
: u8x8
) -> u16x8
{
173 let a
= u16x8
::from(a
);
174 let b
= u16x8
::from(b
);
180 #[target_feature(enable = "neon")]
181 #[cfg_attr(test, assert_instr(uaddl))]
182 pub unsafe fn vaddl_u16(a
: u16x4
, b
: u16x4
) -> u32x4
{
183 let a
= u32x4
::from(a
);
184 let b
= u32x4
::from(b
);
190 #[target_feature(enable = "neon")]
191 #[cfg_attr(test, assert_instr(uaddl))]
192 pub unsafe fn vaddl_u32(a
: u32x2
, b
: u32x2
) -> u64x2
{
193 let a
= u64x2
::from(a
);
194 let b
= u64x2
::from(b
);
198 #[allow(improper_ctypes)]
200 // The Reference says this instruction is
201 // supported in v7/A32/A64:
202 #[link_name = "llvm.aarch64.neon.frsqrte.v2f32"]
203 fn frsqrte_v2f32(a
: f32x2
) -> f32x2
;
206 /// Reciprocal square-root estimate.
208 #[target_feature(enable = "neon")]
209 #[cfg_attr(test, assert_instr(frsqrte))]
210 pub unsafe fn vrsqrte_f32(a
: f32x2
) -> f32x2
{
214 /// Vector narrow integer.
216 #[target_feature(enable = "neon")]
217 #[cfg_attr(test, assert_instr(xtn))]
218 pub unsafe fn vmovn_s16(a
: i16x8
) -> i8x8
{
222 /// Vector narrow integer.
224 #[target_feature(enable = "neon")]
225 #[cfg_attr(test, assert_instr(xtn))]
226 pub unsafe fn vmovn_s32(a
: i32x4
) -> i16x4
{
230 /// Vector narrow integer.
232 #[target_feature(enable = "neon")]
233 #[cfg_attr(test, assert_instr(xtn))]
234 pub unsafe fn vmovn_s64(a
: i64x2
) -> i32x2
{
238 /// Vector narrow integer.
240 #[target_feature(enable = "neon")]
241 #[cfg_attr(test, assert_instr(xtn))]
242 pub unsafe fn vmovn_u16(a
: u16x8
) -> u8x8
{
246 /// Vector narrow integer.
248 #[target_feature(enable = "neon")]
249 #[cfg_attr(test, assert_instr(xtn))]
250 pub unsafe fn vmovn_u32(a
: u32x4
) -> u16x4
{
254 /// Vector narrow integer.
256 #[target_feature(enable = "neon")]
257 #[cfg_attr(test, assert_instr(xtn))]
258 pub unsafe fn vmovn_u64(a
: u64x2
) -> u32x2
{
262 /// Vector long move.
264 #[target_feature(enable = "neon")]
265 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
266 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sxtl))]
267 pub unsafe fn vmovl_s8(a
: i8x8
) -> i16x8
{
271 /// Vector long move.
273 #[target_feature(enable = "neon")]
274 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
275 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sxtl))]
276 pub unsafe fn vmovl_s16(a
: i16x4
) -> i32x4
{
280 /// Vector long move.
282 #[target_feature(enable = "neon")]
283 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
284 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sxtl))]
285 pub unsafe fn vmovl_s32(a
: i32x2
) -> i64x2
{
289 /// Vector long move.
291 #[target_feature(enable = "neon")]
292 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
293 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uxtl))]
294 pub unsafe fn vmovl_u8(a
: u8x8
) -> u16x8
{
298 /// Vector long move.
300 #[target_feature(enable = "neon")]
301 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
302 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uxtl))]
303 pub unsafe fn vmovl_u16(a
: u16x4
) -> u32x4
{
307 /// Vector long move.
309 #[target_feature(enable = "neon")]
310 #[cfg_attr(all(test, target_arch = "arm"), assert_instr(sshll))]
311 #[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uxtl))]
312 pub unsafe fn vmovl_u32(a
: u32x2
) -> u64x2
{
318 use stdsimd_test
::simd_test
;
320 use coresimd
::arm
::neon
;
322 #[simd_test = "neon"]
323 unsafe fn vadd_s8() {
324 let a
= i8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
325 let b
= i8x8
::new(8, 7, 6, 5, 4, 3, 2, 1);
326 let e
= i8x8
::new(9, 9, 9, 9, 9, 9, 9, 9);
327 let r
= neon
::vadd_s8(a
, b
);
331 #[simd_test = "neon"]
332 unsafe fn vaddq_s8() {
333 let a
= i8x16
::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
334 let b
= i8x16
::new(8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1);
335 let e
= i8x16
::new(9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9);
336 let r
= neon
::vaddq_s8(a
, b
);
340 #[simd_test = "neon"]
341 unsafe fn vadd_s16() {
342 let a
= i16x4
::new(1, 2, 3, 4);
343 let b
= i16x4
::new(8, 7, 6, 5);
344 let e
= i16x4
::new(9, 9, 9, 9);
345 let r
= neon
::vadd_s16(a
, b
);
349 #[simd_test = "neon"]
350 unsafe fn vaddq_s16() {
351 let a
= i16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
352 let b
= i16x8
::new(8, 7, 6, 5, 4, 3, 2, 1);
353 let e
= i16x8
::new(9, 9, 9, 9, 9, 9, 9, 9);
354 let r
= neon
::vaddq_s16(a
, b
);
358 #[simd_test = "neon"]
359 unsafe fn vadd_s32() {
360 let a
= i32x2
::new(1, 2);
361 let b
= i32x2
::new(8, 7);
362 let e
= i32x2
::new(9, 9);
363 let r
= neon
::vadd_s32(a
, b
);
367 #[simd_test = "neon"]
368 unsafe fn vaddq_s32() {
369 let a
= i32x4
::new(1, 2, 3, 4);
370 let b
= i32x4
::new(8, 7, 6, 5);
371 let e
= i32x4
::new(9, 9, 9, 9);
372 let r
= neon
::vaddq_s32(a
, b
);
376 #[simd_test = "neon"]
377 unsafe fn vadd_u8() {
378 let a
= u8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
379 let b
= u8x8
::new(8, 7, 6, 5, 4, 3, 2, 1);
380 let e
= u8x8
::new(9, 9, 9, 9, 9, 9, 9, 9);
381 let r
= neon
::vadd_u8(a
, b
);
385 #[simd_test = "neon"]
386 unsafe fn vaddq_u8() {
387 let a
= u8x16
::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
388 let b
= u8x16
::new(8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1);
389 let e
= u8x16
::new(9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9);
390 let r
= neon
::vaddq_u8(a
, b
);
394 #[simd_test = "neon"]
395 unsafe fn vadd_u16() {
396 let a
= u16x4
::new(1, 2, 3, 4);
397 let b
= u16x4
::new(8, 7, 6, 5);
398 let e
= u16x4
::new(9, 9, 9, 9);
399 let r
= neon
::vadd_u16(a
, b
);
403 #[simd_test = "neon"]
404 unsafe fn vaddq_u16() {
405 let a
= u16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
406 let b
= u16x8
::new(8, 7, 6, 5, 4, 3, 2, 1);
407 let e
= u16x8
::new(9, 9, 9, 9, 9, 9, 9, 9);
408 let r
= neon
::vaddq_u16(a
, b
);
412 #[simd_test = "neon"]
413 unsafe fn vadd_u32() {
414 let a
= u32x2
::new(1, 2);
415 let b
= u32x2
::new(8, 7);
416 let e
= u32x2
::new(9, 9);
417 let r
= neon
::vadd_u32(a
, b
);
421 #[simd_test = "neon"]
422 unsafe fn vaddq_u32() {
423 let a
= u32x4
::new(1, 2, 3, 4);
424 let b
= u32x4
::new(8, 7, 6, 5);
425 let e
= u32x4
::new(9, 9, 9, 9);
426 let r
= neon
::vaddq_u32(a
, b
);
430 #[simd_test = "neon"]
431 unsafe fn vadd_f32() {
432 let a
= f32x2
::new(1., 2.);
433 let b
= f32x2
::new(8., 7.);
434 let e
= f32x2
::new(9., 9.);
435 let r
= neon
::vadd_f32(a
, b
);
439 #[simd_test = "neon"]
440 unsafe fn vaddq_f32() {
441 let a
= f32x4
::new(1., 2., 3., 4.);
442 let b
= f32x4
::new(8., 7., 6., 5.);
443 let e
= f32x4
::new(9., 9., 9., 9.);
444 let r
= neon
::vaddq_f32(a
, b
);
448 #[simd_test = "neon"]
449 unsafe fn vaddl_s8() {
450 let v
= ::std
::i8::MAX
;
451 let a
= i8x8
::new(v
, v
, v
, v
, v
, v
, v
, v
);
452 let v
= 2 * (v
as i16);
453 let e
= i16x8
::new(v
, v
, v
, v
, v
, v
, v
, v
);
454 let r
= neon
::vaddl_s8(a
, a
);
458 #[simd_test = "neon"]
459 unsafe fn vaddl_s16() {
460 let v
= ::std
::i16::MAX
;
461 let a
= i16x4
::new(v
, v
, v
, v
);
462 let v
= 2 * (v
as i32);
463 let e
= i32x4
::new(v
, v
, v
, v
);
464 let r
= neon
::vaddl_s16(a
, a
);
468 #[simd_test = "neon"]
469 unsafe fn vaddl_s32() {
470 let v
= ::std
::i32::MAX
;
471 let a
= i32x2
::new(v
, v
);
472 let v
= 2 * (v
as i64);
473 let e
= i64x2
::new(v
, v
);
474 let r
= neon
::vaddl_s32(a
, a
);
478 #[simd_test = "neon"]
479 unsafe fn vaddl_u8() {
480 let v
= ::std
::u8::MAX
;
481 let a
= u8x8
::new(v
, v
, v
, v
, v
, v
, v
, v
);
482 let v
= 2 * (v
as u16);
483 let e
= u16x8
::new(v
, v
, v
, v
, v
, v
, v
, v
);
484 let r
= neon
::vaddl_u8(a
, a
);
488 #[simd_test = "neon"]
489 unsafe fn vaddl_u16() {
490 let v
= ::std
::u16::MAX
;
491 let a
= u16x4
::new(v
, v
, v
, v
);
492 let v
= 2 * (v
as u32);
493 let e
= u32x4
::new(v
, v
, v
, v
);
494 let r
= neon
::vaddl_u16(a
, a
);
498 #[simd_test = "neon"]
499 unsafe fn vaddl_u32() {
500 let v
= ::std
::u32::MAX
;
501 let a
= u32x2
::new(v
, v
);
502 let v
= 2 * (v
as u64);
503 let e
= u64x2
::new(v
, v
);
504 let r
= neon
::vaddl_u32(a
, a
);
508 #[simd_test = "neon"]
509 unsafe fn vrsqrt_f32() {
510 let a
= f32x2
::new(1.0, 2.0);
511 let e
= f32x2
::new(0.9980469, 0.7050781);
512 let r
= neon
::vrsqrte_f32(a
);
516 #[simd_test = "neon"]
517 unsafe fn vmovn_s16() {
518 let a
= i16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
519 let e
= i8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
520 let r
= neon
::vmovn_s16(a
);
524 #[simd_test = "neon"]
525 unsafe fn vmovn_s32() {
526 let a
= i32x4
::new(1, 2, 3, 4);
527 let e
= i16x4
::new(1, 2, 3, 4);
528 let r
= neon
::vmovn_s32(a
);
532 #[simd_test = "neon"]
533 unsafe fn vmovn_s64() {
534 let a
= i64x2
::new(1, 2);
535 let e
= i32x2
::new(1, 2);
536 let r
= neon
::vmovn_s64(a
);
540 #[simd_test = "neon"]
541 unsafe fn vmovn_u16() {
542 let a
= u16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
543 let e
= u8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
544 let r
= neon
::vmovn_u16(a
);
548 #[simd_test = "neon"]
549 unsafe fn vmovn_u32() {
550 let a
= u32x4
::new(1, 2, 3, 4);
551 let e
= u16x4
::new(1, 2, 3, 4);
552 let r
= neon
::vmovn_u32(a
);
556 #[simd_test = "neon"]
557 unsafe fn vmovn_u64() {
558 let a
= u64x2
::new(1, 2);
559 let e
= u32x2
::new(1, 2);
560 let r
= neon
::vmovn_u64(a
);
564 #[simd_test = "neon"]
565 unsafe fn vmovl_s8() {
566 let e
= i16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
567 let a
= i8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
568 let r
= neon
::vmovl_s8(a
);
572 #[simd_test = "neon"]
573 unsafe fn vmovl_s16() {
574 let e
= i32x4
::new(1, 2, 3, 4);
575 let a
= i16x4
::new(1, 2, 3, 4);
576 let r
= neon
::vmovl_s16(a
);
580 #[simd_test = "neon"]
581 unsafe fn vmovl_s32() {
582 let e
= i64x2
::new(1, 2);
583 let a
= i32x2
::new(1, 2);
584 let r
= neon
::vmovl_s32(a
);
588 #[simd_test = "neon"]
589 unsafe fn vmovl_u8() {
590 let e
= u16x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
591 let a
= u8x8
::new(1, 2, 3, 4, 5, 6, 7, 8);
592 let r
= neon
::vmovl_u8(a
);
596 #[simd_test = "neon"]
597 unsafe fn vmovl_u16() {
598 let e
= u32x4
::new(1, 2, 3, 4);
599 let a
= u16x4
::new(1, 2, 3, 4);
600 let r
= neon
::vmovl_u16(a
);
604 #[simd_test = "neon"]
605 unsafe fn vmovl_u32() {
606 let e
= u64x2
::new(1, 2);
607 let a
= u32x2
::new(1, 2);
608 let r
= neon
::vmovl_u32(a
);