diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index adf8067987e40..26c7a9166e68e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -53,6 +53,7 @@ pub enum CallConv { X86_64_SysV = 78, X86_64_Win64 = 79, X86_VectorCall = 80, + X86_Intr = 83, } /// LLVMRustLinkage diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index b44cd20e4402e..0bbe981f2f72c 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -355,6 +355,7 @@ impl FnType { Aapcs => llvm::ArmAapcsCallConv, PtxKernel => llvm::PtxKernel, Msp430Interrupt => llvm::Msp430Intr, + X86Interrupt => llvm::X86_Intr, // These API constants ought to be more specific... Cdecl => llvm::CCallConv, diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 42f3aa5ffd6bd..30641515a41dd 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -25,6 +25,7 @@ pub enum Abi { SysV64, PtxKernel, Msp430Interrupt, + X86Interrupt, // Multiplatform / generic ABIs Rust, @@ -59,6 +60,7 @@ const AbiDatas: &'static [AbiData] = &[ AbiData {abi: Abi::SysV64, name: "sysv64", generic: false }, AbiData {abi: Abi::PtxKernel, name: "ptx-kernel", generic: false }, AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, + AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, // Cross-platform ABIs AbiData {abi: Abi::Rust, name: "Rust", generic: true }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c2b72edb66c6c..78f13c18dc104 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -330,6 +330,9 @@ declare_features! ( // Used to identify crates that contain sanitizer runtimes // rustc internal (active, sanitizer_runtime, "1.17.0", None), + + // `extern "x86-interrupt" fn()` + (active, abi_x86_interrupt, "1.17.0", Some(40180)), ); declare_features! ( @@ -1036,6 +1039,10 @@ impl<'a> PostExpansionVisitor<'a> { gate_feature_post!(&self, abi_msp430_interrupt, span, "msp430-interrupt ABI is experimental and subject to change"); }, + Abi::X86Interrupt => { + gate_feature_post!(&self, abi_x86_interrupt, span, + "x86-interrupt ABI is experimental and subject to change"); + }, // Stable Abi::Cdecl | Abi::Stdcall | diff --git a/src/test/codegen/abi-x86-interrupt.rs b/src/test/codegen/abi-x86-interrupt.rs new file mode 100644 index 0000000000000..838cd4bf6d745 --- /dev/null +++ b/src/test/codegen/abi-x86-interrupt.rs @@ -0,0 +1,28 @@ +// Copyright 2017 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. + +// Checks if the correct annotation for the x86-interrupt ABI is passed to +// llvm. Also checks that the abi_x86_interrupt feature gate allows usage +// of the x86-interrupt abi. + +// ignore-arm +// ignore-aarch64 +// min-llvm-version 3.8 + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(abi_x86_interrupt)] + +// CHECK: define x86_intrcc i64 @has_x86_interrupt_abi +#[no_mangle] +pub extern "x86-interrupt" fn has_x86_interrupt_abi(a: i64) -> i64 { + a * 2 +} diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs index 41efb92d450e8..b77c9fab7169f 100644 --- a/src/test/compile-fail/feature-gate-abi.rs +++ b/src/test/compile-fail/feature-gate-abi.rs @@ -12,6 +12,7 @@ // gate-test-platform_intrinsics // gate-test-abi_vectorcall // gate-test-abi_ptx +// gate-test-abi_x86_interrupt // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change @@ -20,6 +21,7 @@ extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change +extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental // Methods in trait definition trait Tr { @@ -29,6 +31,7 @@ trait Tr { extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental @@ -36,6 +39,7 @@ trait Tr { extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental } struct S; @@ -48,6 +52,7 @@ impl Tr for S { extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental } // Methods in inherent impl @@ -58,6 +63,7 @@ impl S { extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental } // Function pointer types @@ -67,6 +73,7 @@ type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and sub type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change +type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental // Foreign modules extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change @@ -75,5 +82,6 @@ extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to chang extern "rust-call" {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change +extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental fn main() {} diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 423cc9230e893..eef8793511529 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -1,4 +1,4 @@ -error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` +error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` --> $DIR/unicode.rs:11:8 | 11 | extern "路濫狼á́́" fn foo() {}