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/asm/mod.rs33
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs6
2 files changed, 37 insertions, 2 deletions
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(())