about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-01-16 09:23:18 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2015-01-17 11:55:46 +1100
commit4f08de84c923f08535e9a6f754b2776286ebcd01 (patch)
tree5fa4ae2e25fed9186773d71e93aab70b500da39e /src
parent9e83ae931c802608962fb5f9c90220d80d2eaa1c (diff)
downloadrust-4f08de84c923f08535e9a6f754b2776286ebcd01.tar.gz
rust-4f08de84c923f08535e9a6f754b2776286ebcd01.zip
Add comprehensive test for no-ICE behaviour of SIMD FFI.
This just compiles a test using SIMD in FFI (mostly importing LLVM
intrinsics) for almost all rustc's supported platforms, but not linking
it or running it, so there's absolutely no guarantee that this is correct.
Diffstat (limited to 'src')
-rw-r--r--src/test/run-make/simd-ffi/Makefile33
-rwxr-xr-xsrc/test/run-make/simd-ffi/simd.rs81
2 files changed, 114 insertions, 0 deletions
diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make/simd-ffi/Makefile
new file mode 100644
index 00000000000..68a6a5fbfe8
--- /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 00000000000..d5945db9479
--- /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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;
+    }
+}