Rollup merge of #133422 - taiki-e:riscv-e-clobber-abi, r=Amanieu

Fix clobber_abi in RV32E and RV64E inline assembly

Currently clobber_abi in RV32E and RV64E inline assembly is implemented using InlineAsmClobberAbi::RiscV, but broken since x16-x31 cannot be used in RV32E and RV64E.

```
error: cannot use register `x16`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^

error: cannot use register `x17`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^

error: cannot use register `x28`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^

error: cannot use register `x29`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^

error: cannot use register `x30`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^

error: cannot use register `x31`: register can't be used with the `e` target feature
  --> <source>:42:14
   |
42 |     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
   |              ^^^^^^^^^^^^^^^^
```

r? `@Amanieu`

`@rustbot` label O-riscv +A-inline-assembly
This commit is contained in:
Guillaume Gomez
2024-11-28 12:06:01 +01:00
committed by GitHub
5 changed files with 95 additions and 6 deletions

View File

@@ -929,6 +929,7 @@ pub enum InlineAsmClobberAbi {
AArch64NoX18,
Arm64EC,
RiscV,
RiscVE,
LoongArch,
PowerPC,
S390x,
@@ -941,6 +942,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();
@@ -975,7 +977,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 {
@@ -1148,6 +1154,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

View File

@@ -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(())