diff options
Diffstat (limited to 'tests/run-make/simd-ffi')
-rw-r--r-- | tests/run-make/simd-ffi/Makefile | 47 | ||||
-rw-r--r-- | tests/run-make/simd-ffi/simd.rs | 82 |
2 files changed, 129 insertions, 0 deletions
diff --git a/tests/run-make/simd-ffi/Makefile b/tests/run-make/simd-ffi/Makefile new file mode 100644 index 000000000..297353470 --- /dev/null +++ b/tests/run-make/simd-ffi/Makefile @@ -0,0 +1,47 @@ +include ../tools.mk + +TARGETS = +ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm) +# construct a fairly exhaustive list of platforms that we +# support. These ones don't follow a pattern +TARGETS += arm-linux-androideabi arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabi +endif + +ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86) +X86_ARCHS = i686 x86_64 +else +X86_ARCHS = +endif + +# these ones do, each OS lists the architectures it supports +LINUX=$(filter aarch64 mips,$(LLVM_COMPONENTS)) $(X86_ARCHS) +ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips) +LINUX += mipsel +endif + +WINDOWS=$(X86_ARCHS) +# fails with: failed to get iphonesimulator SDK path: no such file or directory +#IOS=i386 aarch64 armv7 +DARWIN=$(X86_ARCHS) + +$(foreach arch,$(LINUX),$(eval TARGETS += $(arch)-unknown-linux-gnu)) +$(foreach arch,$(WINDOWS),$(eval TARGETS += $(arch)-pc-windows-gnu)) +#$(foreach arch,$(IOS),$(eval TARGETS += $(arch)-apple-ios)) +$(foreach arch,$(DARWIN),$(eval TARGETS += $(arch)-apple-darwin)) + +all: $(TARGETS) + +define MK_TARGETS +# compile the rust file to the given target, but only to asm and IR +# form, to avoid having to have an appropriate linker. +# +# we need some features because the integer SIMD instructions are not +# enabled by-default for i686 and ARM; these features will be invalid +# on some platforms, but LLVM just prints a warning so that's fine for +# now. +$(1): simd.rs + $$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs \ + -C target-feature='+neon,+sse2' -C extra-filename=-$(1) +endef + +$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx)))) diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs new file mode 100644 index 000000000..d11cfd77c --- /dev/null +++ b/tests/run-make/simd-ffi/simd.rs @@ -0,0 +1,82 @@ +// ensures that public symbols are not removed completely +#![crate_type = "lib"] +// we can compile to a variety of platforms, because we don't need +// cross-compiled standard libraries. +#![feature(no_core, auto_traits)] +#![no_core] +#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)] + +#[derive(Copy)] +#[repr(simd)] +pub struct f32x4(f32, f32, f32, f32); + +extern "C" { + #[link_name = "llvm.sqrt.v4f32"] + fn vsqrt(x: f32x4) -> f32x4; +} + +pub fn foo(x: f32x4) -> f32x4 { + unsafe { vsqrt(x) } +} + +#[derive(Copy)] +#[repr(simd)] +pub struct i32x4(i32, i32, i32, i32); + +extern "C" { + // _mm_sll_epi32 + #[cfg(any(target_arch = "x86", target_arch = "x86-64"))] + #[link_name = "llvm.x86.sse2.psll.d"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + + // vmaxq_s32 + #[cfg(target_arch = "arm")] + #[link_name = "llvm.arm.neon.vmaxs.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + // vmaxq_s32 + #[cfg(target_arch = "aarch64")] + #[link_name = "llvm.aarch64.neon.maxs.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + + // just some substitute foreign symbol, not an LLVM intrinsic; so + // we still get type checking, but not as detailed as (ab)using + // LLVM. + #[cfg(not(any( + target_arch = "x86", + target_arch = "x86-64", + target_arch = "arm", + target_arch = "aarch64" + )))] + fn integer(a: i32x4, b: i32x4) -> i32x4; +} + +pub fn bar(a: i32x4, b: i32x4) -> i32x4 { + unsafe { integer(a, b) } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +pub trait Copy {} + +impl Copy for f32 {} +impl Copy for i32 {} + +pub mod marker { + pub use Copy; +} + +#[lang = "freeze"] +auto trait Freeze {} + +#[macro_export] +#[rustc_builtin_macro] +macro_rules! Copy { + () => {}; +} +#[macro_export] +#[rustc_builtin_macro] +macro_rules! derive { + () => {}; +} |