feat: `riscv-interrupt-{m,s}` calling conventions

Similar to prior support added for the mips430, avr, and x86 targets
this change implements the rough equivalent of clang's
[`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling
e.g.

```rust
static mut CNT: usize = 0;

pub extern "riscv-interrupt-m" fn isr_m() {
    unsafe {
        CNT += 1;
    }
}
```

to produce highly effective assembly like:

```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0:       1141                    addi    sp,sp,-16
    unsafe {
        CNT += 1;
420003a2:       c62a                    sw      a0,12(sp)
420003a4:       c42e                    sw      a1,8(sp)
420003a6:       3fc80537                lui     a0,0x3fc80
420003aa:       63c52583                lw      a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae:       0585                    addi    a1,a1,1
420003b0:       62b52e23                sw      a1,1596(a0)
    }
}
420003b4:       4532                    lw      a0,12(sp)
420003b6:       45a2                    lw      a1,8(sp)
420003b8:       0141                    addi    sp,sp,16
420003ba:       30200073                mret
```

(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)

This outcome is superior to hand-coded interrupt routines which, lacking
visibility into any non-assembly body of the interrupt handler, have to
be very conservative and save the [entire CPU state to the stack
frame][full-frame-save]. By instead asking LLVM to only save the
registers that it uses, we defer the decision to the tool with the best
context: it can more accurately account for the cost of spills if it
knows that every additional register used is already at the cost of an
implicit spill.

At the LLVM level, this is apparently [implemented by] marking every
register as "[callee-save]," matching the semantics of an interrupt
handler nicely (it has to leave the CPU state just as it found it after
its `{m|s}ret`).

This approach is not suitable for every interrupt handler, as it makes
no attempt to e.g. save the state in a user-accessible stack frame. For
a full discussion of those challenges and tradeoffs, please refer to
[the interrupt calling conventions RFC][rfc].

Inside rustc, this implementation differs from prior art because LLVM
does not expose the "all-saved" function flavor as a calling convention
directly, instead preferring to use an attribute that allows for
differentiating between "machine-mode" and "superivsor-mode" interrupts.

Finally, some effort has been made to guide those who may not yet be
aware of the differences between machine-mode and supervisor-mode
interrupts as to why no `riscv-interrupt` calling convention is exposed
through rustc, and similarly for why `riscv-interrupt-u` makes no
appearance (as it would complicate future LLVM upgrades).

[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
This commit is contained in:
Seth Pellegrino 2023-05-23 15:08:23 -07:00
parent f88a8b71ce
commit 897c7bb23b
27 changed files with 492 additions and 58 deletions

View File

@ -31,9 +31,26 @@ pub struct InvalidAbi {
pub abi: Symbol,
pub command: String,
#[subdiagnostic]
pub explain: Option<InvalidAbiReason>,
#[subdiagnostic]
pub suggestion: Option<InvalidAbiSuggestion>,
}
pub struct InvalidAbiReason(pub &'static str);
impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
#[allow(rustc::untranslatable_diagnostic)]
diag.note(self.0);
}
}
#[derive(Subdiagnostic)]
#[suggestion(
ast_lowering_invalid_abi_suggestion,

View File

@ -1,4 +1,4 @@
use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
use super::ResolverAstLoweringExt;
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
use super::{FnDeclKind, LoweringContext, ParamMode};
@ -1271,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
self.error_on_invalid_abi(abi, err);
abi::Abi::Rust
})
}
@ -1285,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
fn error_on_invalid_abi(&self, abi: StrLit) {
fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) {
let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
.iter()
.map(|s| Symbol::intern(s))
@ -1294,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.tcx.sess.emit_err(InvalidAbi {
abi: abi.symbol_unescaped,
span: abi.span,
explain: match err {
abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
_ => None,
},
suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
span: abi.span,
suggestion: format!("\"{suggested_name}\""),

View File

@ -48,7 +48,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
default_call_conv
}
Conv::X86Intr => sess.fatal("x86-interrupt call conv not yet implemented"),
Conv::X86Intr | Conv::RiscvInterrupt { .. } => {
sess.fatal(format!("interrupt call conv {c:?} not yet implemented"))
}
Conv::ArmAapcs => sess.fatal("aapcs call conv not yet implemented"),
Conv::CCmseNonSecureCall => {

View File

@ -383,13 +383,16 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
let mut func_attrs = SmallVec::<[_; 2]>::new();
let mut func_attrs = SmallVec::<[_; 3]>::new();
if self.ret.layout.abi.is_uninhabited() {
func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
}
if !self.can_unwind {
func_attrs.push(llvm::AttributeKind::NoUnwind.create_attr(cx.llcx));
}
if let Conv::RiscvInterrupt { kind } = self.conv {
func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str()));
}
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs });
let mut i = 0;
@ -565,7 +568,9 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
impl From<Conv> for llvm::CallConv {
fn from(conv: Conv) -> Self {
match conv {
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => {
llvm::CCallConv
}
Conv::RustCold => llvm::ColdCallConv,
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
Conv::AvrInterrupt => llvm::AvrInterrupt,

View File

@ -313,6 +313,8 @@ declare_features! (
(active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
/// Allows `extern "ptx-*" fn()`.
(active, abi_ptx, "1.15.0", Some(38788), None),
/// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
(active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None),
/// Allows `extern "x86-interrupt" fn()`.
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
/// Allows additional const parameter types, such as `&'static str` or user defined types

View File

@ -1239,6 +1239,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
| EfiApi
| AvrInterrupt
| AvrNonBlockingInterrupt
| RiscvInterruptM
| RiscvInterruptS
| CCmseNonSecureCall
| Wasm
| PlatformIntrinsic

View File

@ -30,6 +30,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
| EfiApi
| AvrInterrupt
| AvrNonBlockingInterrupt
| RiscvInterruptM
| RiscvInterruptS
| CCmseNonSecureCall
| Wasm
| RustIntrinsic

View File

@ -326,6 +326,7 @@ symbols! {
abi_efiapi,
abi_msp430_interrupt,
abi_ptx,
abi_riscv_interrupt,
abi_sysv64,
abi_thiscall,
abi_unadjusted,

View File

@ -603,6 +603,25 @@ pub enum Conv {
AmdGpuKernel,
AvrInterrupt,
AvrNonBlockingInterrupt,
RiscvInterrupt {
kind: RiscvInterruptKind,
},
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum RiscvInterruptKind {
Machine,
Supervisor,
}
impl RiscvInterruptKind {
pub fn as_str(&self) -> &'static str {
match self {
Self::Machine => "machine",
Self::Supervisor => "supervisor",
}
}
}
/// Metadata describing how the arguments to a native function
@ -753,6 +772,12 @@ impl FromStr for Conv {
"AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
"AvrInterrupt" => Ok(Conv::AvrInterrupt),
"AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
"RiscvInterrupt(machine)" => {
Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine })
}
"RiscvInterrupt(supervisor)" => {
Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor })
}
_ => Err(format!("'{s}' is not a valid value for entry function call convention.")),
}
}

View File

@ -92,6 +92,7 @@ impl<A: ToJson> ToJson for Option<A> {
impl ToJson for crate::abi::call::Conv {
fn to_json(&self) -> Json {
let buf: String;
let s = match self {
Self::C => "C",
Self::Rust => "Rust",
@ -110,6 +111,10 @@ impl ToJson for crate::abi::call::Conv {
Self::AmdGpuKernel => "AmdGpuKernel",
Self::AvrInterrupt => "AvrInterrupt",
Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
Self::RiscvInterrupt { kind } => {
buf = format!("RiscvInterrupt({})", kind.as_str());
&buf
}
};
Json::String(s.to_owned())
}

View File

@ -38,6 +38,8 @@ pub enum Abi {
PlatformIntrinsic,
Unadjusted,
RustCold,
RiscvInterruptM,
RiscvInterruptS,
}
impl Abi {
@ -107,11 +109,29 @@ const AbiDatas: &[AbiData] = &[
AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
AbiData { abi: Abi::RustCold, name: "rust-cold" },
AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" },
AbiData { abi: Abi::RiscvInterruptS, name: "riscv-interrupt-s" },
];
#[derive(Copy, Clone, Debug)]
pub enum AbiUnsupported {
Unrecognized,
Reason { explain: &'static str },
}
/// Returns the ABI with the given name (if any).
pub fn lookup(name: &str) -> Option<Abi> {
AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
pub fn lookup(name: &str) -> Result<Abi, AbiUnsupported> {
AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi).ok_or_else(|| match name {
"riscv-interrupt" => AbiUnsupported::Reason {
explain: "please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively",
},
"riscv-interrupt-u" => AbiUnsupported::Reason {
explain: "user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314",
},
_ => AbiUnsupported::Unrecognized,
})
}
pub fn all_names() -> Vec<&'static str> {
@ -200,6 +220,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
feature: sym::abi_avr_interrupt,
explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
}),
"riscv-interrupt-m" | "riscv-interrupt-s" => Err(AbiDisabled::Unstable {
feature: sym::abi_riscv_interrupt,
explain: "riscv-interrupt ABIs are experimental and subject to change",
}),
"C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable {
feature: sym::abi_c_cmse_nonsecure_call,
explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
@ -260,6 +284,8 @@ impl Abi {
PlatformIntrinsic => 32,
Unadjusted => 33,
RustCold => 34,
RiscvInterruptM => 35,
RiscvInterruptS => 36,
};
debug_assert!(
AbiDatas

View File

@ -4,19 +4,19 @@ use super::*;
#[test]
fn lookup_Rust() {
let abi = lookup("Rust");
assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
assert!(abi.is_ok() && abi.unwrap().data().name == "Rust");
}
#[test]
fn lookup_cdecl() {
let abi = lookup("cdecl");
assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
assert!(abi.is_ok() && abi.unwrap().data().name == "cdecl");
}
#[test]
fn lookup_baz() {
let abi = lookup("baz");
assert!(abi.is_none());
assert!(matches!(abi, Err(AbiUnsupported::Unrecognized)))
}
#[test]

View File

@ -2267,6 +2267,7 @@ impl Target {
PtxKernel => self.arch == "nvptx64",
Msp430Interrupt => self.arch == "msp430",
AmdGpuKernel => self.arch == "amdgcn",
RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
Thiscall { .. } => self.arch == "x86",
@ -2698,7 +2699,7 @@ impl Target {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match lookup_abi(s) {
Some(abi) => base.$key_name = Some(abi),
Ok(abi) => base.$key_name = Some(abi),
_ => return Some(Err(format!("'{}' is not a valid value for abi", s))),
}
Some(Ok(()))

View File

@ -9,6 +9,7 @@ use rustc_session::config::OptLevel;
use rustc_span::def_id::DefId;
use rustc_target::abi::call::{
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind,
RiscvInterruptKind,
};
use rustc_target::abi::*;
use rustc_target::spec::abi::Abi as SpecAbi;
@ -193,6 +194,8 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
AmdGpuKernel => Conv::AmdGpuKernel,
AvrInterrupt => Conv::AvrInterrupt,
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },
RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor },
Wasm => Conv::C,
// These API constants ought to be more specific...

View File

@ -30,6 +30,8 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
"efiapi",
"avr-interrupt",
"avr-non-blocking-interrupt",
"riscv-interrupt-m",
"riscv-interrupt-s",
"C-cmse-nonsecure-call",
"wasm",
"system",

View File

@ -0,0 +1,27 @@
error[E0703]: invalid ABI: found `riscv-interrupt`
--> $DIR/riscv-discoverability-guidance.rs:17:8
|
LL | extern "riscv-interrupt" fn isr() {}
| ^^^^^^^^^^^^^^^^^
| |
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
error[E0703]: invalid ABI: found `riscv-interrupt-u`
--> $DIR/riscv-discoverability-guidance.rs:23:8
|
LL | extern "riscv-interrupt-u" fn isr_U() {}
| ^^^^^^^^^^^^^^^^^^^
| |
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0703`.

View File

@ -0,0 +1,27 @@
error[E0703]: invalid ABI: found `riscv-interrupt`
--> $DIR/riscv-discoverability-guidance.rs:17:8
|
LL | extern "riscv-interrupt" fn isr() {}
| ^^^^^^^^^^^^^^^^^
| |
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
error[E0703]: invalid ABI: found `riscv-interrupt-u`
--> $DIR/riscv-discoverability-guidance.rs:23:8
|
LL | extern "riscv-interrupt-u" fn isr_U() {}
| ^^^^^^^^^^^^^^^^^^^
| |
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0703`.

View File

@ -0,0 +1,27 @@
// ignore-tidy-linelength
// revisions: riscv32 riscv64
//
// [riscv32] needs-llvm-components: riscv
// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib
// [riscv64] needs-llvm-components: riscv
// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib
#![no_core]
#![feature(
no_core,
lang_items,
abi_riscv_interrupt
)]
#[lang = "sized"]
trait Sized {}
extern "riscv-interrupt" fn isr() {}
//~^ ERROR invalid ABI
//~^^ NOTE invalid ABI
//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
//~^^^^ NOTE please use one of riscv-interrupt-m or riscv-interrupt-s
extern "riscv-interrupt-u" fn isr_U() {}
//~^ ERROR invalid ABI
//~^^ NOTE invalid ABI
//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
//~^^^^ NOTE user-mode interrupt handlers have been removed from LLVM pending standardization

View File

@ -1,53 +1,59 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:25:1
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:27:1
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:29:1
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"aapcs"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:31:1
--> $DIR/unsupported.rs:36:1
|
LL | extern "aapcs" fn aapcs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:35:1
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:37:1
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:46:1
|
LL | extern "riscv-interrupt-m" fn riscv() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:39:1
--> $DIR/unsupported.rs:51:1
|
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"thiscall"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:42:1
--> $DIR/unsupported.rs:56:1
|
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of calling convention not supported on this target
--> $DIR/unsupported.rs:46:1
--> $DIR/unsupported.rs:62:1
|
LL | extern "stdcall" fn stdcall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -56,6 +62,6 @@ LL | extern "stdcall" fn stdcall() {}
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
= note: `#[warn(unsupported_calling_conventions)]` on by default
error: aborting due to 8 previous errors; 1 warning emitted
error: aborting due to 9 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0570`.

View File

@ -1,47 +1,53 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:25:1
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:27:1
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:29:1
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:35:1
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:37:1
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:46:1
|
LL | extern "riscv-interrupt-m" fn riscv() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:39:1
--> $DIR/unsupported.rs:51:1
|
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"thiscall"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:42:1
--> $DIR/unsupported.rs:56:1
|
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of calling convention not supported on this target
--> $DIR/unsupported.rs:46:1
--> $DIR/unsupported.rs:62:1
|
LL | extern "stdcall" fn stdcall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {}
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
= note: `#[warn(unsupported_calling_conventions)]` on by default
error: aborting due to 7 previous errors; 1 warning emitted
error: aborting due to 8 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0570`.

View File

@ -1,39 +1,45 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:25:1
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:27:1
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:29:1
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"aapcs"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:31:1
--> $DIR/unsupported.rs:36:1
|
LL | extern "aapcs" fn aapcs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:35:1
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:37:1
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:46:1
|
LL | extern "riscv-interrupt-m" fn riscv() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0570`.

View File

@ -0,0 +1,61 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"aapcs"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:36:1
|
LL | extern "aapcs" fn aapcs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:51:1
|
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"thiscall"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:56:1
|
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of calling convention not supported on this target
--> $DIR/unsupported.rs:62:1
|
LL | extern "stdcall" fn stdcall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
= note: `#[warn(unsupported_calling_conventions)]` on by default
error: aborting due to 8 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0570`.

View File

@ -0,0 +1,61 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"aapcs"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:36:1
|
LL | extern "aapcs" fn aapcs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:51:1
|
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"thiscall"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:56:1
|
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of calling convention not supported on this target
--> $DIR/unsupported.rs:62:1
|
LL | extern "stdcall" fn stdcall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
= note: `#[warn(unsupported_calling_conventions)]` on by default
error: aborting due to 8 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0570`.

View File

@ -1,4 +1,4 @@
// revisions: x64 i686 aarch64 arm
// revisions: x64 i686 aarch64 arm riscv32 riscv64
//
// [x64] needs-llvm-components: x86
// [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
@ -8,6 +8,10 @@
// [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=rlib
// [arm] needs-llvm-components: arm
// [arm] compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib
// [riscv32] needs-llvm-components: riscv
// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib
// [riscv64] needs-llvm-components: riscv
// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib
#![no_core]
#![feature(
no_core,
@ -17,10 +21,11 @@
abi_avr_interrupt,
abi_amdgpu_kernel,
wasm_abi,
abi_x86_interrupt
abi_x86_interrupt,
abi_riscv_interrupt
)]
#[lang="sized"]
trait Sized { }
#[lang = "sized"]
trait Sized {}
extern "ptx-kernel" fn ptx() {}
//~^ ERROR is not a supported ABI
@ -32,21 +37,36 @@ extern "aapcs" fn aapcs() {}
//[x64]~^ ERROR is not a supported ABI
//[i686]~^^ ERROR is not a supported ABI
//[aarch64]~^^^ ERROR is not a supported ABI
//[riscv32]~^^^^ ERROR is not a supported ABI
//[riscv64]~^^^^^ ERROR is not a supported ABI
extern "msp430-interrupt" fn msp430() {}
//~^ ERROR is not a supported ABI
extern "avr-interrupt" fn avr() {}
//~^ ERROR is not a supported ABI
extern "riscv-interrupt-m" fn riscv() {}
//[arm]~^ ERROR is not a supported ABI
//[x64]~^^ ERROR is not a supported ABI
//[i686]~^^^ ERROR is not a supported ABI
//[aarch64]~^^^^ ERROR is not a supported ABI
extern "x86-interrupt" fn x86() {}
//[aarch64]~^ ERROR is not a supported ABI
//[arm]~^^ ERROR is not a supported ABI
//[riscv32]~^^^ ERROR is not a supported ABI
//[riscv64]~^^^^ ERROR is not a supported ABI
extern "thiscall" fn thiscall() {}
//[x64]~^ ERROR is not a supported ABI
//[aarch64]~^^ ERROR is not a supported ABI
//[arm]~^^^ ERROR is not a supported ABI
//[arm]~^^ ERROR is not a supported ABI
//[aarch64]~^^^ ERROR is not a supported ABI
//[riscv32]~^^^^ ERROR is not a supported ABI
//[riscv64]~^^^^^ ERROR is not a supported ABI
extern "stdcall" fn stdcall() {}
//[x64]~^ WARN use of calling convention not supported
//[x64]~^^ WARN this was previously accepted
//[aarch64]~^^^ WARN use of calling convention not supported
//[aarch64]~^^^^ WARN this was previously accepted
//[arm]~^^^^^ WARN use of calling convention not supported
//[arm]~^^^^^^ WARN this was previously accepted
//[arm]~^^^ WARN use of calling convention not supported
//[arm]~^^^^ WARN this was previously accepted
//[aarch64]~^^^^^ WARN use of calling convention not supported
//[aarch64]~^^^^^^ WARN this was previously accepted
//[riscv32]~^^^^^^^ WARN use of calling convention not supported
//[riscv32]~^^^^^^^^ WARN this was previously accepted
//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported
//[riscv64]~^^^^^^^^^^ WARN this was previously accepted

View File

@ -1,47 +1,53 @@
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:25:1
--> $DIR/unsupported.rs:30:1
|
LL | extern "ptx-kernel" fn ptx() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:27:1
--> $DIR/unsupported.rs:32:1
|
LL | extern "amdgpu-kernel" fn amdgpu() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"wasm"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:29:1
--> $DIR/unsupported.rs:34:1
|
LL | extern "wasm" fn wasm() {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"aapcs"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:31:1
--> $DIR/unsupported.rs:36:1
|
LL | extern "aapcs" fn aapcs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:35:1
--> $DIR/unsupported.rs:42:1
|
LL | extern "msp430-interrupt" fn msp430() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:37:1
--> $DIR/unsupported.rs:44:1
|
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:46:1
|
LL | extern "riscv-interrupt-m" fn riscv() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0570]: `"thiscall"` is not a supported ABI for the current target
--> $DIR/unsupported.rs:42:1
--> $DIR/unsupported.rs:56:1
|
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of calling convention not supported on this target
--> $DIR/unsupported.rs:46:1
--> $DIR/unsupported.rs:62:1
|
LL | extern "stdcall" fn stdcall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {}
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
= note: `#[warn(unsupported_calling_conventions)]` on by default
error: aborting due to 7 previous errors; 1 warning emitted
error: aborting due to 8 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0570`.

View File

@ -0,0 +1,33 @@
// needs-llvm-components: riscv
// compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib
#![no_core]
#![feature(no_core, lang_items)]
#[lang = "sized"]
trait Sized {}
// Test that the riscv interrupt ABIs cannot be used when riscv_interrupt
// feature gate is not used.
extern "riscv-interrupt-m" fn f() {}
//~^ ERROR riscv-interrupt ABIs are experimental
extern "riscv-interrupt-s" fn f_s() {}
//~^ ERROR riscv-interrupt ABIs are experimental
trait T {
extern "riscv-interrupt-m" fn m();
//~^ ERROR riscv-interrupt ABIs are experimental
}
struct S;
impl T for S {
extern "riscv-interrupt-m" fn m() {}
//~^ ERROR riscv-interrupt ABIs are experimental
}
impl S {
extern "riscv-interrupt-m" fn im() {}
//~^ ERROR riscv-interrupt ABIs are experimental
}
type TA = extern "riscv-interrupt-m" fn();
//~^ ERROR riscv-interrupt ABIs are experimental

View File

@ -0,0 +1,57 @@
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:11:8
|
LL | extern "riscv-interrupt-m" fn f() {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8
|
LL | extern "riscv-interrupt-s" fn f_s() {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:17:12
|
LL | extern "riscv-interrupt-m" fn m();
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:23:12
|
LL | extern "riscv-interrupt-m" fn m() {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:28:12
|
LL | extern "riscv-interrupt-m" fn im() {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error[E0658]: riscv-interrupt ABIs are experimental and subject to change
--> $DIR/feature-gate-abi-riscv-interrupt.rs:32:18
|
LL | type TA = extern "riscv-interrupt-m" fn();
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
= help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.