1
Fork 0

Fix clobber_abi in RV32E and RV64E inline assembly

This commit is contained in:
Taiki Endo 2024-11-25 00:36:22 +09:00
parent ab3cf268b5
commit 736c397f41
5 changed files with 95 additions and 6 deletions

View file

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

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