about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs11
-rw-r--r--compiler/rustc_target/src/asm/mod.rs33
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs6
4 files changed, 51 insertions, 6 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 215e6d84d0f..32559a10ac3 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -80,7 +80,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let mut clobber_abis = FxIndexMap::default();
         if let Some(asm_arch) = asm_arch {
             for (abi_name, abi_span) in &asm.clobber_abis {
-                match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
+                match asm::InlineAsmClobberAbi::parse(
+                    asm_arch,
+                    &self.tcx.sess.target,
+                    &self.tcx.sess.unstable_target_features,
+                    *abi_name,
+                ) {
                     Ok(abi) => {
                         // If the abi was already in the list, emit an error
                         match clobber_abis.get(&abi) {
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 70176754f33..73ee47b2c63 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -472,9 +472,14 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
         let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
 
         // Allocate stack slots for saving clobbered registers
-        let abi_clobber = InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, sym::C)
-            .unwrap()
-            .clobbered_regs();
+        let abi_clobber = InlineAsmClobberAbi::parse(
+            self.arch,
+            &self.tcx.sess.target,
+            &self.tcx.sess.unstable_target_features,
+            sym::C,
+        )
+        .unwrap()
+        .clobbered_regs();
         for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) {
             let mut need_save = true;
             // If the register overlaps with a register clobbered by function call, then
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 10778e9acf1..2c5ad1aa8bf 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -922,6 +922,7 @@ pub enum InlineAsmClobberAbi {
     AArch64NoX18,
     Arm64EC,
     RiscV,
+    RiscVE,
     LoongArch,
     PowerPC,
     S390x,
@@ -934,6 +935,7 @@ impl InlineAsmClobberAbi {
     pub fn parse(
         arch: InlineAsmArch,
         target: &Target,
+        target_features: &FxIndexSet<Symbol>,
         name: Symbol,
     ) -> Result<Self, &'static [&'static str]> {
         let name = name.as_str();
@@ -968,7 +970,11 @@ impl InlineAsmClobberAbi {
                 _ => Err(&["C", "system"]),
             },
             InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
-                "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV),
+                "C" | "system" | "efiapi" => Ok(if riscv::is_e(target_features) {
+                    InlineAsmClobberAbi::RiscVE
+                } else {
+                    InlineAsmClobberAbi::RiscV
+                }),
                 _ => Err(&["C", "system", "efiapi"]),
             },
             InlineAsmArch::LoongArch64 => match name {
@@ -1141,6 +1147,31 @@ impl InlineAsmClobberAbi {
                     v24, v25, v26, v27, v28, v29, v30, v31,
                 }
             },
+            InlineAsmClobberAbi::RiscVE => clobbered_regs! {
+                RiscV RiscVInlineAsmReg {
+                    // Refs:
+                    // - ILP32E https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#ilp32e-calling-convention
+                    // - LP64E https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/299
+
+                    // ra
+                    x1,
+                    // t0-t2
+                    x5, x6, x7,
+                    // a0-a5
+                    x10, x11, x12, x13, x14, x15,
+                    // ft0-ft7
+                    f0, f1, f2, f3, f4, f5, f6, f7,
+                    // fa0-fa7
+                    f10, f11, f12, f13, f14, f15, f16, f17,
+                    // ft8-ft11
+                    f28, f29, f30, f31,
+
+                    v0, v1, v2, v3, v4, v5, v6, v7,
+                    v8, v9, v10, v11, v12, v13, v14, v15,
+                    v16, v17, v18, v19, v20, v21, v22, v23,
+                    v24, v25, v26, v27, v28, v29, v30, v31,
+                }
+            },
             InlineAsmClobberAbi::LoongArch => clobbered_regs! {
                 LoongArch LoongArchInlineAsmReg {
                     // ra
diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
index cfd573efbc1..d6b30525379 100644
--- a/compiler/rustc_target/src/asm/riscv.rs
+++ b/compiler/rustc_target/src/asm/riscv.rs
@@ -54,6 +54,10 @@ impl RiscVInlineAsmRegClass {
     }
 }
 
+pub(crate) fn is_e(target_features: &FxIndexSet<Symbol>) -> bool {
+    target_features.contains(&sym::e)
+}
+
 fn not_e(
     _arch: InlineAsmArch,
     _reloc_model: RelocModel,
@@ -61,7 +65,7 @@ fn not_e(
     _target: &Target,
     _is_clobber: bool,
 ) -> Result<(), &'static str> {
-    if target_features.contains(&sym::e) {
+    if is_e(target_features) {
         Err("register can't be used with the `e` target feature")
     } else {
         Ok(())