diff options
| author | CensoredUsername <cens.username@gmail.com> | 2016-08-27 15:14:51 +0200 |
|---|---|---|
| committer | CensoredUsername <cens.username@gmail.com> | 2016-08-30 16:03:06 +0200 |
| commit | 0e58a5d139772404ab936b6c7679e9ff936101c4 (patch) | |
| tree | 2453b34c80fde922db92e9fb212730d6f5bba2a7 | |
| parent | 30c4173cb8f942afbb1588174e5867eb780cdaa0 (diff) | |
| download | rust-0e58a5d139772404ab936b6c7679e9ff936101c4.tar.gz rust-0e58a5d139772404ab936b6c7679e9ff936101c4.zip | |
Feature gate the sysv64 abi as feature(abi_sysv64) and add tests
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 23 | ||||
| -rw-r--r-- | src/test/codegen/abi-sysv64.rs | 24 | ||||
| -rw-r--r-- | src/test/compile-fail/feature-gate-abi-sysv64.rs | 19 | ||||
| -rw-r--r-- | src/test/run-pass/abi-sysv64-register-usage.rs | 125 |
4 files changed, 184 insertions, 7 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1e15c156356..18924a3dc25 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -281,7 +281,11 @@ declare_features! ( (active, never_type, "1.13.0", Some(35121)), // Allows all literals in attribute lists and values of key-value pairs. - (active, attr_literals, "1.13.0", Some(34981)) + (active, attr_literals, "1.13.0", Some(34981)), + + // Allows the sysV64 ABI to be specified on all platforms + // instead of just the platforms on which it is the C ABI + (active, abi_sysv64, "1.13.0", None) ); declare_features! ( @@ -811,21 +815,26 @@ macro_rules! gate_feature_post { impl<'a> PostExpansionVisitor<'a> { fn check_abi(&self, abi: Abi, span: Span) { match abi { - Abi::RustIntrinsic => + Abi::RustIntrinsic => { gate_feature_post!(&self, intrinsics, span, - "intrinsics are subject to change"), + "intrinsics are subject to change"); + }, Abi::PlatformIntrinsic => { gate_feature_post!(&self, platform_intrinsics, span, - "platform intrinsics are experimental and possibly buggy") + "platform intrinsics are experimental and possibly buggy"); }, Abi::Vectorcall => { gate_feature_post!(&self, abi_vectorcall, span, - "vectorcall is experimental and subject to change") - } + "vectorcall is experimental and subject to change"); + }, Abi::RustCall => { gate_feature_post!(&self, unboxed_closures, span, "rust-call ABI is subject to change"); - } + }, + Abi::SysV64 => { + gate_feature_post!(&self, abi_sysv64, span, + "sysv64 ABI is experimental and subject to change"); + }, _ => {} } } diff --git a/src/test/codegen/abi-sysv64.rs b/src/test/codegen/abi-sysv64.rs new file mode 100644 index 00000000000..2b8e8a1b6b2 --- /dev/null +++ b/src/test/codegen/abi-sysv64.rs @@ -0,0 +1,24 @@ +// Copyright 2016 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. + +// Checks if the correct annotation for the sysv64 ABI is passed to +// llvm. Also checks that the abi-sysv64 feature gate allows usage +// of the sysv64 abi. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(abi_sysv64)] + +// CHECK: define x86_64_sysvcc i64 @has_sysv64_abi +#[no_mangle] +pub extern "sysv64" fn has_sysv64_abi(a: i64) -> i64 { + a * 2 +} diff --git a/src/test/compile-fail/feature-gate-abi-sysv64.rs b/src/test/compile-fail/feature-gate-abi-sysv64.rs new file mode 100644 index 00000000000..2a4aae8c06b --- /dev/null +++ b/src/test/compile-fail/feature-gate-abi-sysv64.rs @@ -0,0 +1,19 @@ +// Copyright 2016 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. + +// Test that the sysv64 ABI cannot be used when abi-sysv64 feature +// gate is not used. + +extern "sysv64" fn foo() {} +//~^ ERROR sysv64 ABI is experimental and subject to change + +fn main() { + foo(); +} diff --git a/src/test/run-pass/abi-sysv64-register-usage.rs b/src/test/run-pass/abi-sysv64-register-usage.rs new file mode 100644 index 00000000000..5e58240359e --- /dev/null +++ b/src/test/run-pass/abi-sysv64-register-usage.rs @@ -0,0 +1,125 @@ +// Copyright 2016 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. + +// Checks if the correct registers are being used to pass arguments +// when the sysv64 ABI is specified. + +#![feature(abi_sysv64)] +#![feature(naked_functions)] +#![feature(asm)] + +#[naked] +#[inline(never)] +#[allow(unused_variables)] +pub unsafe extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64, + rcx: i64, r8 : i64, r9 : i64, + xmm0: f32, xmm1: f32, xmm2: f32, + xmm3: f32, xmm4: f32, xmm5: f32, + xmm6: f32, xmm7: f32) -> i64 { + // this assembly checks all registers for specific values, and puts in rax + // how many values were correct. + asm!("cmp rdi, 0x1; + xor rax, rax; + setz al; + + cmp rsi, 0x2; + xor rdi, rdi + setz dil; + add rax, rdi; + + cmp rdx, 0x3; + setz dil; + add rax, rdi; + + cmp rcx, 0x4; + setz dil; + add rax, rdi; + + cmp r8, 0x5; + setz dil; + add rax, rdi; + + cmp r9, 0x6; + setz dil; + add rax, rdi; + + movd esi, xmm0; + cmp rsi, 0x3F800000; + setz dil; + add rax, rdi; + + movd esi, xmm1; + cmp rsi, 0x40000000; + setz dil; + add rax, rdi; + + movd esi, xmm2; + cmp rsi, 0x40800000; + setz dil; + add rax, rdi; + + movd esi, xmm3; + cmp rsi, 0x41000000; + setz dil; + add rax, rdi; + + movd esi, xmm4; + cmp rsi, 0x41800000; + setz dil; + add rax, rdi; + + movd esi, xmm5; + cmp rsi, 0x42000000; + setz dil; + add rax, rdi; + + movd esi, xmm6; + cmp rsi, 0x42800000; + setz dil; + add rax, rdi; + + movd esi, xmm7; + cmp rsi, 0x43000000; + setz dil; + add rax, rdi; + ret + " :::: "intel"); + unreachable!(); +} + +// this struct contains 8 i64's, while only 6 can be passed in registers. +#[derive(PartialEq, Eq, Debug)] +pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64); + +#[inline(never)] +pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct { + foo.0 *= 1; + foo.1 *= 2; + foo.2 *= 3; + foo.3 *= 4; + foo.4 *= 5; + foo.5 *= 6; + foo.6 *= 7; + foo.7 *= 8; + foo +} + +pub fn main() { + assert_eq!(unsafe { + all_the_registers(1, 2, 3, 4, 5, 6, + 1.0, 2.0, 4.0, 8.0, + 16.0, 32.0, 64.0, 128.0) + }, 14); + + assert_eq!( + large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)), + LargeStruct(1, 4, 9, 16, 25, 36, 49, 64) + ); +} |
