about summary refs log tree commit diff
path: root/compiler/rustc_target/src/spec
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src/spec')
-rw-r--r--compiler/rustc_target/src/spec/abi.rs30
-rw-r--r--compiler/rustc_target/src/spec/abi/tests.rs6
-rw-r--r--compiler/rustc_target/src/spec/mod.rs3
3 files changed, 33 insertions, 6 deletions
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index dc233121f66..550cdf6bda6 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -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
diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs
index 8bea5e5efe3..251a12fe7aa 100644
--- a/compiler/rustc_target/src/spec/abi/tests.rs
+++ b/compiler/rustc_target/src/spec/abi/tests.rs
@@ -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]
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index c215a7c4b6e..523a64441c7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -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(()))