about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/abi/call/csky.rs31
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs27
-rw-r--r--compiler/rustc_target/src/abi/mod.rs7
-rw-r--r--compiler/rustc_target/src/asm/csky.rs128
-rw-r--r--compiler/rustc_target/src/asm/mod.rs24
-rw-r--r--compiler/rustc_target/src/json.rs5
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs16
-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/csky_unknown_linux_gnuabiv2.rs20
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none.rs3
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs3
-rw-r--r--compiler/rustc_target/src/spec/mod.rs9
-rw-r--r--compiler/rustc_target/src/spec/teeos_base.rs29
14 files changed, 328 insertions, 10 deletions
diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs
new file mode 100644
index 00000000000..bbe95fa20ac
--- /dev/null
+++ b/compiler/rustc_target/src/abi/call/csky.rs
@@ -0,0 +1,31 @@
+// See https://github.com/llvm/llvm-project/blob/d85b94bf0080dcd780656c0f5e6342800720eba9/llvm/lib/Target/CSKY/CSKYCallingConv.td
+use crate::abi::call::{ArgAbi, FnAbi};
+
+fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
+    if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
+        ret.make_indirect();
+    } else {
+        ret.extend_integer_width_to(32);
+    }
+}
+
+fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
+    if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 {
+        arg.make_indirect();
+    } else {
+        arg.extend_integer_width_to(32);
+    }
+}
+
+pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+    if !fn_abi.ret.is_ignore() {
+        classify_ret(&mut fn_abi.ret);
+    }
+
+    for arg in fn_abi.args.iter_mut() {
+        if arg.is_ignore() {
+            continue;
+        }
+        classify_arg(arg);
+    }
+}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 3d2ea017d8f..8fab13d5d5d 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -9,6 +9,7 @@ mod amdgpu;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -603,6 +604,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
@@ -693,6 +713,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "avr" => avr::compute_abi_info(self),
             "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
+            "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
             "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self),
             "powerpc" => powerpc::compute_abi_info(self),
@@ -753,6 +774,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.")),
         }
     }
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 084c917cc31..dd435dbb0a3 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -39,7 +39,7 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
 
 /// Trait that needs to be implemented by the higher-level type representation
 /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
-pub trait TyAbiInterface<'a, C>: Sized {
+pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug {
     fn ty_and_layout_for_variant(
         this: TyAndLayout<'a, Self>,
         cx: &C,
@@ -135,6 +135,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
         for index in indices {
             offset += layout.fields.offset(index);
             layout = layout.field(cx, index);
+            assert!(
+                layout.is_sized(),
+                "offset of unsized field (type {:?}) cannot be computed statically",
+                layout.ty
+            );
         }
 
         offset
diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs
new file mode 100644
index 00000000000..6f0e7f79949
--- /dev/null
+++ b/compiler/rustc_target/src/asm/csky.rs
@@ -0,0 +1,128 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use rustc_span::Symbol;
+use std::fmt;
+
+def_reg_class! {
+    CSKY CSKYInlineAsmRegClass {
+        reg,
+        freg,
+    }
+}
+
+impl CSKYInlineAsmRegClass {
+    pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+        &[]
+    }
+
+    pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+        None
+    }
+
+    pub fn suggest_modifier(
+        self,
+        _arch: InlineAsmArch,
+        _ty: InlineAsmType,
+    ) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn supported_types(
+        self,
+        _arch: InlineAsmArch,
+    ) -> &'static [(InlineAsmType, Option<Symbol>)] {
+        match self {
+            Self::reg => types! { _: I8, I16, I32; },
+            Self::freg => types! { _: F32; },
+        }
+    }
+}
+
+// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp#79>
+def_regs! {
+    CSKY CSKYInlineAsmReg CSKYInlineAsmRegClass {
+        r0: reg = ["r0","a0"],
+        r1: reg = ["r1","a1"],
+        r2: reg = ["r2","a2"],
+        r3: reg = ["r3","a3"],
+        r4: reg = ["r4","l0"],
+        r5: reg = ["r5","l1"],
+        r6: reg = ["r6","l2"],
+        r9: reg = ["r9","l5"],// feature e2
+        r10: reg = ["r10","l6"],// feature e2
+        r11: reg = ["r11","l7"],// feature e2
+        r12: reg = ["r12","t0"],// feature e2
+        r13: reg = ["r13","t1"],// feature e2
+        r16: reg = ["r16","l8"],// feature high-register
+        r17: reg = ["r17","l9"],// feature high-register
+        r18: reg = ["r18","t2"],// feature high-register
+        r19: reg = ["r19","t3"],// feature high-register
+        r20: reg = ["r20","t4"],// feature high-register
+        r21: reg = ["r21","t5"],// feature high-register
+        r22: reg = ["r22","t6"],// feature high-register
+        r23: reg = ["r23","t7", "fp"],// feature high-register
+        r24: reg = ["r24","t8", "sop"],// feature high-register
+        r25: reg = ["r25","t9","tp", "bsp"],// feature high-register
+        f0: freg = ["fr0","vr0"],
+        f1: freg = ["fr1","vr1"],
+        f2: freg = ["fr2","vr2"],
+        f3: freg = ["fr3","vr3"],
+        f4: freg = ["fr4","vr4"],
+        f5: freg = ["fr5","vr5"],
+        f6: freg = ["fr6","vr6"],
+        f7: freg = ["fr7","vr7"],
+        f8: freg = ["fr8","vr8"],
+        f9: freg = ["fr9","vr9"],
+        f10: freg = ["fr10","vr10"],
+        f11: freg = ["fr11","vr11"],
+        f12: freg = ["fr12","vr12"],
+        f13: freg = ["fr13","vr13"],
+        f14: freg = ["fr14","vr14"],
+        f15: freg = ["fr15","vr15"],
+        f16: freg = ["fr16","vr16"],
+        f17: freg = ["fr17","vr17"],
+        f18: freg = ["fr18","vr18"],
+        f19: freg = ["fr19","vr19"],
+        f20: freg = ["fr20","vr20"],
+        f21: freg = ["fr21","vr21"],
+        f22: freg = ["fr22","vr22"],
+        f23: freg = ["fr23","vr23"],
+        f24: freg = ["fr24","vr24"],
+        f25: freg = ["fr25","vr25"],
+        f26: freg = ["fr26","vr26"],
+        f27: freg = ["fr27","vr27"],
+        f28: freg = ["fr28","vr28"],
+        f29: freg = ["fr29","vr29"],
+        f30: freg = ["fr30","vr30"],
+        f31: freg = ["fr31","vr31"],
+        #error = ["r7", "l3"] =>
+            "the base pointer cannot be used as an operand for inline asm",
+        #error = ["r8","l4"] =>
+            "the frame pointer cannot be used as an operand for inline asm",
+        #error = ["r14","sp"] =>
+            "the stack pointer cannot be used as an operand for inline asm",
+        #error = ["r15","lr"] =>
+            "the link register cannot be used as an operand for inline asm",
+        #error = ["r31","tls"] =>
+            "reserver for tls",
+        #error = ["r28", "gb", "rgb", "rdb"] =>
+            "the global pointer cannot be used as an operand for inline asm",
+        #error = ["r26","r27","r29","tb", "rtb", "r30","svbr"] =>
+            "reserved by the ABI",
+    }
+}
+
+impl CSKYInlineAsmReg {
+    pub fn emit(
+        self,
+        out: &mut dyn fmt::Write,
+        _arch: InlineAsmArch,
+        _modifier: Option<char>,
+    ) -> fmt::Result {
+        out.write_str(self.name())
+    }
+}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 7c27732079b..a11884bea26 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -167,6 +167,7 @@ mod aarch64;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -184,6 +185,7 @@ pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
 pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
 pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
 pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
+pub use csky::{CSKYInlineAsmReg, CSKYInlineAsmRegClass};
 pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
 pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
 pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
@@ -220,6 +222,7 @@ pub enum InlineAsmArch {
     Avr,
     Msp430,
     M68k,
+    CSKY,
 }
 
 impl FromStr for InlineAsmArch {
@@ -248,6 +251,7 @@ impl FromStr for InlineAsmArch {
             "avr" => Ok(Self::Avr),
             "msp430" => Ok(Self::Msp430),
             "m68k" => Ok(Self::M68k),
+            "csky" => Ok(Self::CSKY),
             _ => Err(()),
         }
     }
@@ -272,6 +276,7 @@ pub enum InlineAsmReg {
     Avr(AvrInlineAsmReg),
     Msp430(Msp430InlineAsmReg),
     M68k(M68kInlineAsmReg),
+    CSKY(CSKYInlineAsmReg),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -292,6 +297,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => "<reg>",
         }
     }
@@ -311,6 +317,7 @@ impl InlineAsmReg {
             Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
             Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
             Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()),
+            Self::CSKY(r) => InlineAsmRegClass::CSKY(r.reg_class()),
             Self::Err => InlineAsmRegClass::Err,
         }
     }
@@ -344,6 +351,7 @@ impl InlineAsmReg {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmReg::parse(name)?),
         })
     }
 
@@ -371,6 +379,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+            Self::CSKY(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Err => unreachable!(),
         }
     }
@@ -397,6 +406,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.emit(out, arch, modifier),
             Self::Msp430(r) => r.emit(out, arch, modifier),
             Self::M68k(r) => r.emit(out, arch, modifier),
+            Self::CSKY(r) => r.emit(out, arch, modifier),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -416,6 +426,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
             Self::Msp430(_) => cb(self),
             Self::M68k(_) => cb(self),
+            Self::CSKY(_) => cb(self),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -440,6 +451,7 @@ pub enum InlineAsmRegClass {
     Avr(AvrInlineAsmRegClass),
     Msp430(Msp430InlineAsmRegClass),
     M68k(M68kInlineAsmRegClass),
+    CSKY(CSKYInlineAsmRegClass),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -463,6 +475,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => rustc_span::symbol::sym::reg,
         }
     }
@@ -488,6 +501,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
             Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
             Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k),
+            Self::CSKY(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::CSKY),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -520,6 +534,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_modifier(arch, ty),
             Self::Msp430(r) => r.suggest_modifier(arch, ty),
             Self::M68k(r) => r.suggest_modifier(arch, ty),
+            Self::CSKY(r) => r.suggest_modifier(arch, ty),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -548,6 +563,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.default_modifier(arch),
             Self::Msp430(r) => r.default_modifier(arch),
             Self::M68k(r) => r.default_modifier(arch),
+            Self::CSKY(r) => r.default_modifier(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -575,6 +591,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.supported_types(arch),
             Self::Msp430(r) => r.supported_types(arch),
             Self::M68k(r) => r.supported_types(arch),
+            Self::CSKY(r) => r.supported_types(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -607,6 +624,7 @@ impl InlineAsmRegClass {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
         })
     }
 
@@ -630,6 +648,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.valid_modifiers(arch),
             Self::Msp430(r) => r.valid_modifiers(arch),
             Self::M68k(r) => r.valid_modifiers(arch),
+            Self::CSKY(r) => r.valid_modifiers(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -826,6 +845,11 @@ pub fn allocatable_registers(
             m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
         }
+        InlineAsmArch::CSKY => {
+            let mut map = csky::regclass_map();
+            csky::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
+            map
+        }
     }
 }
 
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
index 75bb76a9de0..af455b6432f 100644
--- a/compiler/rustc_target/src/json.rs
+++ b/compiler/rustc_target/src/json.rs
@@ -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())
     }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
new file mode 100644
index 00000000000..64a7dc681c8
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
@@ -0,0 +1,16 @@
+use crate::spec::Target;
+
+pub fn target() -> Target {
+    let mut base = super::teeos_base::opts();
+    base.features = "+strict-align,+neon,+fp-armv8".into();
+    base.max_atomic_width = Some(128);
+    base.linker = Some("aarch64-linux-gnu-ld".into());
+
+    Target {
+        llvm_target: "aarch64-unknown-none".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: base,
+    }
+}
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/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
new file mode 100644
index 00000000000..7d03dd26f5d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
@@ -0,0 +1,20 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+// This target is for glibc Linux on Csky
+
+pub fn target() -> Target {
+    Target {
+        //https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h
+        llvm_target: "csky-unknown-linux-gnuabiv2".into(),
+        pointer_width: 32,
+        data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(),
+        arch: "csky".into(),
+        options: TargetOptions {
+            abi: "abiv2".into(),
+            features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(),
+            late_link_args_static: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a"]),
+            max_atomic_width: Some(32),
+            ..super::linux_gnu_base::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
index 209d481d6f8..dbc96d68eae 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
@@ -10,7 +10,8 @@ pub fn target() -> Target {
         options: TargetOptions {
             cpu: "generic".into(),
             features: "+f,+d".into(),
-            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
index f444a7f24bb..c4d5c7bc44c 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
@@ -11,7 +11,8 @@ pub fn target() -> Target {
             cpu: "generic".into(),
             features: "-f,-d".into(),
             abi: "softfloat".into(),
-            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
             llvm_abiname: "lp64s".into(),
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index c215a7c4b6e..af2b96ccb51 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -83,6 +83,7 @@ mod openbsd_base;
 mod redox_base;
 mod solaris_base;
 mod solid_base;
+mod teeos_base;
 mod thumb_base;
 mod uefi_msvc_base;
 mod unikraft_linux_musl_base;
@@ -337,7 +338,7 @@ impl LinkerFlavor {
             || stem == "clang++"
             || stem.ends_with("-clang++")
         {
-            (Some(Cc::Yes), None)
+            (Some(Cc::Yes), Some(Lld::No))
         } else if stem == "wasm-ld"
             || stem.ends_with("-wasm-ld")
             || stem == "ld.lld"
@@ -1245,6 +1246,7 @@ supported_targets! {
     ("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
     ("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
     ("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
+    ("csky-unknown-linux-gnuabiv2", csky_unknown_linux_gnuabiv2),
     ("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
     ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
     ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
@@ -1494,6 +1496,8 @@ supported_targets! {
 
     ("x86_64-unknown-none", x86_64_unknown_none),
 
+    ("aarch64-unknown-teeos", aarch64_unknown_teeos),
+
     ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl),
 
     ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710),
@@ -2267,6 +2271,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 +2703,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(()))
diff --git a/compiler/rustc_target/src/spec/teeos_base.rs b/compiler/rustc_target/src/spec/teeos_base.rs
new file mode 100644
index 00000000000..1bc71bab016
--- /dev/null
+++ b/compiler/rustc_target/src/spec/teeos_base.rs
@@ -0,0 +1,29 @@
+use super::{Cc, LinkerFlavor, Lld, PanicStrategy};
+use crate::spec::{RelroLevel, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
+    let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
+
+    let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
+    super::add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
+
+    TargetOptions {
+        os: "teeos".into(),
+        vendor: "unknown".into(),
+        dynamic_linking: true,
+        linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        // rpath hardcodes -Wl, so it can't be used together with ld.lld.
+        // C TAs also don't support rpath, so this is fine.
+        has_rpath: false,
+        // Note: Setting has_thread_local to true causes an error when
+        // loading / dyn-linking the TA
+        has_thread_local: false,
+        position_independent_executables: true,
+        relro_level: RelroLevel::Full,
+        crt_static_respected: true,
+        pre_link_args,
+        panic_strategy: PanicStrategy::Abort,
+        ..Default::default()
+    }
+}