1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
//@ assembly-output: emit-asm
//@ compile-flags: -O
//@ compile-flags: --target armv7-unknown-linux-gnueabihf
//@ compile-flags: -C target-feature=+neon
//@ needs-llvm-components: arm
#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[repr(simd)]
pub struct f32x4(f32, f32, f32, f32);
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for f32x4 {}
macro_rules! check {
($func:ident $modifier:literal $reg:ident $ty:ident $mov:literal) => {
// -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
#[no_mangle]
pub unsafe extern "C" fn $func() -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
y
}
};
}
// CHECK-LABEL: reg:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check!(reg "" reg i32 "mov");
// CHECK-LABEL: sreg:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check!(sreg "" sreg f32 "vmov.f32");
// CHECK-LABEL: sreg_low16:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check!(sreg_low16 "" sreg_low16 f32 "vmov.f32");
// CHECK-LABEL: dreg:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg "" dreg f64 "vmov.f64");
// CHECK-LABEL: dreg_low16:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg_low16 "" dreg_low16 f64 "vmov.f64");
// CHECK-LABEL: dreg_low8:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg_low8 "" dreg_low8 f64 "vmov.f64");
// CHECK-LABEL: qreg:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg "" qreg f32x4 "vmov");
// CHECK-LABEL: qreg_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_e "e" qreg f32x4 "vmov.f64");
// CHECK-LABEL: qreg_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_f "f" qreg f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low8:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg_low8 "" qreg_low8 f32x4 "vmov");
// CHECK-LABEL: qreg_low8_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_low8_e "e" qreg_low8 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low8_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_low8_f "f" qreg_low8 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low4:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg_low4 "" qreg_low4 f32x4 "vmov");
// CHECK-LABEL: qreg_low4_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_low4_e "e" qreg_low4 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low4_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_low4_f "f" qreg_low4 f32x4 "vmov.f64");
|