diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make/simd-ffi/Makefile new file mode 100644 index 000000000000..68a6a5fbfe86 --- /dev/null +++ b/src/test/run-make/simd-ffi/Makefile @@ -0,0 +1,33 @@ +-include ../tools.mk + +# 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 + +# these ones do, each OS lists the architectures it supports +LINUX=aarch64 i686 x86_64 mips mipsel +WINDOWS=i686 x86_64 +# fails with: failed to get iphonesimulator SDK path: no such file or directory +#IOS=i386 aarch64 armv7 +DARWIN=i686 x86_64 + +$(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' +endef + +$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx)))) diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs new file mode 100755 index 000000000000..d5945db94791 --- /dev/null +++ b/src/test/run-make/simd-ffi/simd.rs @@ -0,0 +1,81 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// 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. +#![no_std] + +#![feature(simd, link_llvm_intrinsics, lang_items)] + + +#[repr(C)] +#[derive(Copy)] +#[simd] +pub struct f32x4(f32, f32, f32, f32); + + +extern { + #[link_name = "llvm.sqrt.v4f32"] + fn vsqrt(x: f32x4) -> f32x4; +} + +pub fn foo(x: f32x4) -> f32x4 { + unsafe {vsqrt(x)} +} + +#[repr(C)] +#[derive(Copy)] +#[simd] +pub struct i32x4(i32, i32, i32, i32); + + +extern { + // _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(any(target_arch = "arm"))] + #[link_name = "llvm.arm.neon.vmaxs.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + // vmaxq_s32 + #[cfg(any(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"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +mod std { + pub mod marker { + pub use Copy; + } +}