1 // assembly-output: emit-asm
2 // compile-flags: --target armv7-unknown-linux-gnueabihf
3 // compile-flags: -C target-feature=+neon
4 // needs-llvm-components: arm
6 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_sym)]
7 #![crate_type = "rlib"]
9 #![allow(asm_sub_register, non_camel_case_types)]
11 #[rustc_builtin_macro]
15 #[rustc_builtin_macro]
19 #[rustc_builtin_macro]
20 macro_rules! stringify {
32 pub struct i8x8(i8, i8, i8, i8, i8, i8, i8, i8);
34 pub struct i16x4(i16, i16, i16, i16);
36 pub struct i32x2(i32, i32);
38 pub struct i64x1(i64);
40 pub struct f32x2(f32, f32);
42 pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
44 pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
46 pub struct i32x4(i32, i32, i32, i32);
48 pub struct i64x2(i64, i64);
50 pub struct f32x4(f32, f32, f32, f32);
60 impl Copy for i16x4 {}
61 impl Copy for i32x2 {}
62 impl Copy for i64x1 {}
63 impl Copy for f32x2 {}
64 impl Copy for i8x16 {}
65 impl Copy for i16x8 {}
66 impl Copy for i32x4 {}
67 impl Copy for i64x2 {}
68 impl Copy for f32x4 {}
72 static extern_static: u8;
75 // CHECK-LABEL: sym_fn:
77 // CHECK: bl extern_func
80 pub unsafe fn sym_fn() {
81 asm!("bl {}", sym extern_func);
84 // CHECK-LABEL: sym_static:
86 // CHECK: adr r0, extern_static
89 pub unsafe fn sym_static() {
90 asm!("adr r0, {}", sym extern_static);
93 // Regression test for #82052.
94 // CHECK-LABEL: issue_82052
95 // CHECK: push {{.*}}lr
98 pub unsafe fn issue_82052() {
99 asm!("", out("r14") _);
103 ($func:ident $ty:ident $class:ident $mov:literal) => {
105 pub unsafe fn $func(x: $ty) -> $ty {
106 // Hack to avoid function merging
108 fn dont_merge(s: &str);
110 dont_merge(stringify!($func));
113 asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
119 macro_rules! check_reg {
120 ($func:ident $ty:ident $reg:tt $mov:literal) => {
122 pub unsafe fn $func(x: $ty) -> $ty {
123 // Hack to avoid function merging
125 fn dont_merge(s: &str);
127 dont_merge(stringify!($func));
130 asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
136 // CHECK-LABEL: reg_i8:
138 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
140 check!(reg_i8 i8 reg "mov");
142 // CHECK-LABEL: reg_i16:
144 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
146 check!(reg_i16 i16 reg "mov");
148 // CHECK-LABEL: reg_i32:
150 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
152 check!(reg_i32 i32 reg "mov");
154 // CHECK-LABEL: reg_f32:
156 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
158 check!(reg_f32 f32 reg "mov");
160 // CHECK-LABEL: reg_ptr:
162 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
164 check!(reg_ptr ptr reg "mov");
166 // CHECK-LABEL: sreg_i32:
168 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
170 check!(sreg_i32 i32 sreg "vmov.f32");
172 // CHECK-LABEL: sreg_f32:
174 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
176 check!(sreg_f32 f32 sreg "vmov.f32");
178 // CHECK-LABEL: sreg_ptr:
180 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
182 check!(sreg_ptr ptr sreg "vmov.f32");
184 // CHECK-LABEL: sreg_low16_i32:
186 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
188 check!(sreg_low16_i32 i32 sreg_low16 "vmov.f32");
190 // CHECK-LABEL: sreg_low16_f32:
192 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
194 check!(sreg_low16_f32 f32 sreg_low16 "vmov.f32");
196 // CHECK-LABEL: dreg_i64:
198 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
200 check!(dreg_i64 i64 dreg "vmov.f64");
202 // CHECK-LABEL: dreg_f64:
204 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
206 check!(dreg_f64 f64 dreg "vmov.f64");
208 // CHECK-LABEL: dreg_i8x8:
210 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
212 check!(dreg_i8x8 i8x8 dreg "vmov.f64");
214 // CHECK-LABEL: dreg_i16x4:
216 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
218 check!(dreg_i16x4 i16x4 dreg "vmov.f64");
220 // CHECK-LABEL: dreg_i32x2:
222 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
224 check!(dreg_i32x2 i32x2 dreg "vmov.f64");
226 // CHECK-LABEL: dreg_i64x1:
228 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
230 check!(dreg_i64x1 i64x1 dreg "vmov.f64");
232 // CHECK-LABEL: dreg_f32x2:
234 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
236 check!(dreg_f32x2 f32x2 dreg "vmov.f64");
238 // CHECK-LABEL: dreg_low16_i64:
240 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
242 check!(dreg_low16_i64 i64 dreg_low16 "vmov.f64");
244 // CHECK-LABEL: dreg_low16_f64:
246 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
248 check!(dreg_low16_f64 f64 dreg_low16 "vmov.f64");
250 // CHECK-LABEL: dreg_low16_i8x8:
252 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
254 check!(dreg_low16_i8x8 i8x8 dreg_low16 "vmov.f64");
256 // CHECK-LABEL: dreg_low16_i16x4:
258 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
260 check!(dreg_low16_i16x4 i16x4 dreg_low16 "vmov.f64");
262 // CHECK-LABEL: dreg_low16_i32x2:
264 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
266 check!(dreg_low16_i32x2 i32x2 dreg_low16 "vmov.f64");
268 // CHECK-LABEL: dreg_low16_i64x1:
270 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
272 check!(dreg_low16_i64x1 i64x1 dreg_low16 "vmov.f64");
274 // CHECK-LABEL: dreg_low16_f32x2:
276 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
278 check!(dreg_low16_f32x2 f32x2 dreg_low16 "vmov.f64");
280 // CHECK-LABEL: dreg_low8_i64:
282 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
284 check!(dreg_low8_i64 i64 dreg_low8 "vmov.f64");
286 // CHECK-LABEL: dreg_low8_f64:
288 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
290 check!(dreg_low8_f64 f64 dreg_low8 "vmov.f64");
292 // CHECK-LABEL: dreg_low8_i8x8:
294 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
296 check!(dreg_low8_i8x8 i8x8 dreg_low8 "vmov.f64");
298 // CHECK-LABEL: dreg_low8_i16x4:
300 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
302 check!(dreg_low8_i16x4 i16x4 dreg_low8 "vmov.f64");
304 // CHECK-LABEL: dreg_low8_i32x2:
306 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
308 check!(dreg_low8_i32x2 i32x2 dreg_low8 "vmov.f64");
310 // CHECK-LABEL: dreg_low8_i64x1:
312 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
314 check!(dreg_low8_i64x1 i64x1 dreg_low8 "vmov.f64");
316 // CHECK-LABEL: dreg_low8_f32x2:
318 // CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
320 check!(dreg_low8_f32x2 f32x2 dreg_low8 "vmov.f64");
322 // CHECK-LABEL: qreg_i8x16:
324 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
326 check!(qreg_i8x16 i8x16 qreg "vmov");
328 // CHECK-LABEL: qreg_i16x8:
330 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
332 check!(qreg_i16x8 i16x8 qreg "vmov");
334 // CHECK-LABEL: qreg_i32x4:
336 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
338 check!(qreg_i32x4 i32x4 qreg "vmov");
340 // CHECK-LABEL: qreg_i64x2:
342 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
344 check!(qreg_i64x2 i64x2 qreg "vmov");
346 // CHECK-LABEL: qreg_f32x4:
348 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
350 check!(qreg_f32x4 f32x4 qreg "vmov");
352 // CHECK-LABEL: qreg_low8_i8x16:
354 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
356 check!(qreg_low8_i8x16 i8x16 qreg_low8 "vmov");
358 // CHECK-LABEL: qreg_low8_i16x8:
360 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
362 check!(qreg_low8_i16x8 i16x8 qreg_low8 "vmov");
364 // CHECK-LABEL: qreg_low8_i32x4:
366 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
368 check!(qreg_low8_i32x4 i32x4 qreg_low8 "vmov");
370 // CHECK-LABEL: qreg_low8_i64x2:
372 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
374 check!(qreg_low8_i64x2 i64x2 qreg_low8 "vmov");
376 // CHECK-LABEL: qreg_low8_f32x4:
378 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
380 check!(qreg_low8_f32x4 f32x4 qreg_low8 "vmov");
382 // CHECK-LABEL: qreg_low4_i8x16:
384 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
386 check!(qreg_low4_i8x16 i8x16 qreg_low4 "vmov");
388 // CHECK-LABEL: qreg_low4_i16x8:
390 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
392 check!(qreg_low4_i16x8 i16x8 qreg_low4 "vmov");
394 // CHECK-LABEL: qreg_low4_i32x4:
396 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
398 check!(qreg_low4_i32x4 i32x4 qreg_low4 "vmov");
400 // CHECK-LABEL: qreg_low4_i64x2:
402 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
404 check!(qreg_low4_i64x2 i64x2 qreg_low4 "vmov");
406 // CHECK-LABEL: qreg_low4_f32x4:
408 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
410 check!(qreg_low4_f32x4 f32x4 qreg_low4 "vmov");
412 // CHECK-LABEL: r0_i8:
416 check_reg!(r0_i8 i8 "r0" "mov");
418 // CHECK-LABEL: r0_i16:
422 check_reg!(r0_i16 i16 "r0" "mov");
424 // CHECK-LABEL: r0_i32:
428 check_reg!(r0_i32 i32 "r0" "mov");
430 // CHECK-LABEL: r0_f32:
434 check_reg!(r0_f32 f32 "r0" "mov");
436 // CHECK-LABEL: r0_ptr:
440 check_reg!(r0_ptr ptr "r0" "mov");
442 // CHECK-LABEL: s0_i32:
444 // CHECK: vmov.f32 s0, s0
446 check_reg!(s0_i32 i32 "s0" "vmov.f32");
448 // CHECK-LABEL: s0_f32:
450 // CHECK: vmov.f32 s0, s0
452 check_reg!(s0_f32 f32 "s0" "vmov.f32");
454 // CHECK-LABEL: s0_ptr:
456 // CHECK: vmov.f32 s0, s0
458 check_reg!(s0_ptr ptr "s0" "vmov.f32");
460 // CHECK-LABEL: d0_i64:
462 // CHECK: vmov.f64 d0, d0
464 check_reg!(d0_i64 i64 "d0" "vmov.f64");
466 // CHECK-LABEL: d0_f64:
468 // CHECK: vmov.f64 d0, d0
470 check_reg!(d0_f64 f64 "d0" "vmov.f64");
472 // CHECK-LABEL: d0_i8x8:
474 // CHECK: vmov.f64 d0, d0
476 check_reg!(d0_i8x8 i8x8 "d0" "vmov.f64");
478 // CHECK-LABEL: d0_i16x4:
480 // CHECK: vmov.f64 d0, d0
482 check_reg!(d0_i16x4 i16x4 "d0" "vmov.f64");
484 // CHECK-LABEL: d0_i32x2:
486 // CHECK: vmov.f64 d0, d0
488 check_reg!(d0_i32x2 i32x2 "d0" "vmov.f64");
490 // CHECK-LABEL: d0_i64x1:
492 // CHECK: vmov.f64 d0, d0
494 check_reg!(d0_i64x1 i64x1 "d0" "vmov.f64");
496 // CHECK-LABEL: d0_f32x2:
498 // CHECK: vmov.f64 d0, d0
500 check_reg!(d0_f32x2 f32x2 "d0" "vmov.f64");
502 // CHECK-LABEL: q0_i8x16:
504 // CHECK: vorr q0, q0, q0
506 check_reg!(q0_i8x16 i8x16 "q0" "vmov");
508 // CHECK-LABEL: q0_i16x8:
510 // CHECK: vorr q0, q0, q0
512 check_reg!(q0_i16x8 i16x8 "q0" "vmov");
514 // CHECK-LABEL: q0_i32x4:
516 // CHECK: vorr q0, q0, q0
518 check_reg!(q0_i32x4 i32x4 "q0" "vmov");
520 // CHECK-LABEL: q0_i64x2:
522 // CHECK: vorr q0, q0, q0
524 check_reg!(q0_i64x2 i64x2 "q0" "vmov");
526 // CHECK-LABEL: q0_f32x4:
528 // CHECK: vorr q0, q0, q0
530 check_reg!(q0_f32x4 f32x4 "q0" "vmov");