Skip to content

Commit 933f471

Browse files
authored
Auto merge of #34494 - CensoredUsername:allow_sysV64_abi, r=nagisa
Allow specification of the system V AMD64 ABI constraint. This can be specified using `extern "sysV64" fn` on all platforms. This ABI is used as the C ABI on unix platforms, but can only be specified there using extern "C". It was impossible to specify on other platforms. Meanwhile the win64 ABI, which was the extern "C" ABI on the windows platform could be specified on other platforms using extern "win64". This pull request adds the the "sysV64" ABI constraint which exposes this calling convention on platforms where it is not the C ABI.
2 parents 147371f + 3d766a0 commit 933f471

File tree

11 files changed

+519
-9
lines changed

11 files changed

+519
-9
lines changed

src/doc/book/ffi.md

+1
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ This is currently hidden behind the `abi_vectorcall` gate and is subject to chan
539539
* `system`
540540
* `C`
541541
* `win64`
542+
* `sysv64`
542543

543544
Most of the abis in this list are self-explanatory, but the `system` abi may
544545
seem a little odd. This constraint selects whatever the appropriate ABI is for

src/doc/reference.md

+4
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,7 @@ There are also some platform-specific ABI strings:
16771677
* `extern "cdecl"` -- The default for x86\_32 C code.
16781678
* `extern "stdcall"` -- The default for the Win32 API on x86\_32.
16791679
* `extern "win64"` -- The default for C code on x86\_64 Windows.
1680+
* `extern "sysv64"` -- The default for C code on non-Windows x86\_64.
16801681
* `extern "aapcs"` -- The default for ARM.
16811682
* `extern "fastcall"` -- The `fastcall` ABI -- corresponds to MSVC's
16821683
`__fastcall` and GCC and clang's `__attribute__((fastcall))`
@@ -2485,6 +2486,9 @@ The currently implemented features of the reference compiler are:
24852486

24862487
* - `dotdot_in_tuple_patterns` - Allows `..` in tuple (struct) patterns.
24872488

2489+
* - `abi_sysv64` - Allows the usage of the system V AMD64 calling convention
2490+
(e.g. `extern "sysv64" func fn_();`)
2491+
24882492
If a feature is promoted to a language feature, then all existing programs will
24892493
start to receive compilation warnings about `#![feature]` directives which enabled
24902494
the new feature (because the directive is no longer necessary). However, if a

src/librustc_llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub enum CallConv {
4242
ColdCallConv = 9,
4343
X86StdcallCallConv = 64,
4444
X86FastcallCallConv = 65,
45+
X86_64_SysV = 78,
4546
X86_64_Win64 = 79,
4647
X86_VectorCall = 80
4748
}

src/librustc_trans/abi.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ impl FnType {
269269
Vectorcall => llvm::X86_VectorCall,
270270
C => llvm::CCallConv,
271271
Win64 => llvm::X86_64_Win64,
272+
SysV64 => llvm::X86_64_SysV,
272273

273274
// These API constants ought to be more specific...
274275
Cdecl => llvm::CCallConv,
@@ -483,7 +484,9 @@ impl FnType {
483484

484485
match &ccx.sess().target.target.arch[..] {
485486
"x86" => cabi_x86::compute_abi_info(ccx, self),
486-
"x86_64" => if ccx.sess().target.target.options.is_like_windows {
487+
"x86_64" => if abi == Abi::SysV64 {
488+
cabi_x86_64::compute_abi_info(ccx, self);
489+
} else if abi == Abi::Win64 || ccx.sess().target.target.options.is_like_windows {
487490
cabi_x86_win64::compute_abi_info(ccx, self);
488491
} else {
489492
cabi_x86_64::compute_abi_info(ccx, self);

src/libsyntax/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub enum Abi {
3939
Vectorcall,
4040
Aapcs,
4141
Win64,
42+
SysV64,
4243

4344
// Multiplatform ABIs second
4445
Rust,
@@ -86,6 +87,7 @@ const AbiDatas: &'static [AbiData] = &[
8687
AbiData {abi: Abi::Vectorcall, name: "vectorcall"},
8788
AbiData {abi: Abi::Aapcs, name: "aapcs" },
8889
AbiData {abi: Abi::Win64, name: "win64" },
90+
AbiData {abi: Abi::SysV64, name: "sysv64" },
8991

9092
// Cross-platform ABIs
9193
//

src/libsyntax/feature_gate.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,11 @@ declare_features! (
281281
(active, never_type, "1.13.0", Some(35121)),
282282

283283
// Allows all literals in attribute lists and values of key-value pairs.
284-
(active, attr_literals, "1.13.0", Some(34981))
284+
(active, attr_literals, "1.13.0", Some(34981)),
285+
286+
// Allows the sysV64 ABI to be specified on all platforms
287+
// instead of just the platforms on which it is the C ABI
288+
(active, abi_sysv64, "1.13.0", Some(36167))
285289
);
286290

287291
declare_features! (
@@ -811,21 +815,26 @@ macro_rules! gate_feature_post {
811815
impl<'a> PostExpansionVisitor<'a> {
812816
fn check_abi(&self, abi: Abi, span: Span) {
813817
match abi {
814-
Abi::RustIntrinsic =>
818+
Abi::RustIntrinsic => {
815819
gate_feature_post!(&self, intrinsics, span,
816-
"intrinsics are subject to change"),
820+
"intrinsics are subject to change");
821+
},
817822
Abi::PlatformIntrinsic => {
818823
gate_feature_post!(&self, platform_intrinsics, span,
819-
"platform intrinsics are experimental and possibly buggy")
824+
"platform intrinsics are experimental and possibly buggy");
820825
},
821826
Abi::Vectorcall => {
822827
gate_feature_post!(&self, abi_vectorcall, span,
823-
"vectorcall is experimental and subject to change")
824-
}
828+
"vectorcall is experimental and subject to change");
829+
},
825830
Abi::RustCall => {
826831
gate_feature_post!(&self, unboxed_closures, span,
827832
"rust-call ABI is subject to change");
828-
}
833+
},
834+
Abi::SysV64 => {
835+
gate_feature_post!(&self, abi_sysv64, span,
836+
"sysv64 ABI is experimental and subject to change");
837+
},
829838
_ => {}
830839
}
831840
}

src/test/codegen/abi-sysv64.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Checks if the correct annotation for the sysv64 ABI is passed to
12+
// llvm. Also checks that the abi-sysv64 feature gate allows usage
13+
// of the sysv64 abi.
14+
15+
// compile-flags: -C no-prepopulate-passes
16+
17+
#![crate_type = "lib"]
18+
#![feature(abi_sysv64)]
19+
20+
// CHECK: define x86_64_sysvcc i64 @has_sysv64_abi
21+
#[no_mangle]
22+
pub extern "sysv64" fn has_sysv64_abi(a: i64) -> i64 {
23+
a * 2
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the sysv64 ABI cannot be used when abi-sysv64 feature
12+
// gate is not used.
13+
14+
extern "sysv64" fn foo() {}
15+
//~^ ERROR sysv64 ABI is experimental and subject to change
16+
17+
fn main() {
18+
foo();
19+
}

0 commit comments

Comments
 (0)