diff --git a/riscv-rt/CHANGELOG.md b/riscv-rt/CHANGELOG.md index a1b7beb8..427cfcdd 100644 --- a/riscv-rt/CHANGELOG.md +++ b/riscv-rt/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- Patch in assembly code to avoid spurious errors from LLVM ## [v0.12.0] - 2024-01-14 diff --git a/riscv-rt/build.rs b/riscv-rt/build.rs index b0302bb6..fa405808 100644 --- a/riscv-rt/build.rs +++ b/riscv-rt/build.rs @@ -34,8 +34,8 @@ fn parse_target(target: &str, cargo_flags: &str) -> (u32, HashSet) { .unwrap(); let mut extensions: HashSet = arch.chars().skip_while(|c| c.is_ascii_digit()).collect(); - // get rid of the 'g' shorthand extension - if extensions.remove(&'g') { + // expand the 'g' shorthand extension + if extensions.contains(&'g') { extensions.insert('i'); extensions.insert('m'); extensions.insert('a'); diff --git a/riscv-rt/src/asm.rs b/riscv-rt/src/asm.rs index 0eedebe6..ea4b5233 100644 --- a/riscv-rt/src/asm.rs +++ b/riscv-rt/src/asm.rs @@ -19,6 +19,26 @@ macro_rules! cfg_global_asm { }; } +// Provisional patch to avoid LLVM spurious errors when compiling in release mode. +// This patch is somewhat hardcoded and relies on the fact that the rustc compiler +// only supports a limited combination of ISA extensions. This patch should be +// removed when LLVM fixes the issue. Alternatively, it must be updated when rustc +// supports more ISA extension combinations. +// +// Related issues: +// - https://github.com/rust-embedded/riscv/issues/175 +// - https://github.com/rust-lang/rust/issues/80608 +// - https://github.com/llvm/llvm-project/issues/61991 +cfg_global_asm!( + "// Provisional patch to avoid LLVM spurious errors when compiling in release mode.", + #[cfg(all(riscv32, riscvm))] + ".attribute arch, \"rv32im\"", + #[cfg(all(riscv64, riscvm, not(riscvg)))] + ".attribute arch, \"rv64im\"", + #[cfg(all(riscv64, riscvg))] + ".attribute arch, \"rv64g\"", +); + // Entry point of all programs (_start). It initializes DWARF call frame information, // the stack pointer, the frame pointer (needed for closures to work in start_rust) // and the global pointer. Then it calls _start_rust.