From 40b858c4145f357c17f3d15166f6add8dc194090 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 14:52:54 +0000 Subject: [PATCH 1/3] Add rv64IM --- compiler/rustc_target/src/spec/mod.rs | 1 + .../targets/riscv64im_unknown_none_elf.rs | 35 ++++++++++++ src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../riscv64im-unknown-none-elf.md | 54 +++++++++++++++++++ src/tools/build-manifest/src/main.rs | 1 + tests/assembly-llvm/targets/targets-elf.rs | 3 ++ 7 files changed, 96 insertions(+) create mode 100644 compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs create mode 100644 src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2dd0fbc4517a5..05515c951bd77 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1685,6 +1685,7 @@ supported_targets! { ("riscv32imac-unknown-xous-elf", riscv32imac_unknown_xous_elf), ("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu), ("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl), + ("riscv64im-unknown-none-elf", riscv64im_unknown_none_elf), ("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf), ("riscv64gc-unknown-none-elf", riscv64gc_unknown_none_elf), ("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu), diff --git a/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs new file mode 100644 index 0000000000000..6aae40a3f90de --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs @@ -0,0 +1,35 @@ +use crate::spec::{ + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), + llvm_target: "riscv64".into(), + metadata: TargetMetadata { + description: Some("Bare RISC-V (RV64IM ISA)".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + arch: Arch::RiscV64, + + options: TargetOptions { + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + cpu: "generic-rv64".into(), + max_atomic_width: Some(64), + atomic_cas: false, + features: "+m,+forced-atomics".into(), + llvm_abiname: "lp64".into(), + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + code_model: Some(CodeModel::Medium), + emit_debug_gdb_scripts: false, + eh_frame_header: false, + ..Default::default() + }, + } +} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index e4623a2a87f48..9ae228f9646e2 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -111,6 +111,7 @@ - [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) + - [riscv64im-unknown-none-elf](platform-support/riscv64im-unknown-none-elf.md) - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md) - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md) - [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 39bf9c7776401..208c16e0fc8e1 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -184,6 +184,7 @@ target | std | notes [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) +[`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M diff --git a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md new file mode 100644 index 0000000000000..033904959db33 --- /dev/null +++ b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md @@ -0,0 +1,54 @@ +# `riscv64im-unknown-none-elf` + +**Tier: 3** + +Bare-metal target for RISC-V CPUs with the RV64IM ISA. + +## Target maintainers + +* Rust Embedded Working Group, [RISC-V team](https://github.com/rust-embedded/wg#the-risc-v-team) + +## Requirements + +This target is cross-compiled and uses static linking. The target supports `core` and `alloc`, but not `std`. + +The target does not support atomic compare-and-swap operations, as the RV64IM ISA lacks the "A" (Atomics) extension. Atomic operations are emulated using the `+forced-atomics` feature. + +No external toolchain is required and the default `rust-lld` linker works, but you must specify a linker script. The [`riscv-rt`] crate provides suitable linker scripts. The [`riscv-rust-quickstart`] repository gives examples of RISC-V bare-metal projects. + +[`riscv-rt`]: https://crates.io/crates/riscv-rt +[`riscv-rust-quickstart`]: https://github.com/riscv-rust/riscv-rust-quickstart + +## Building the target + +This target is included in Rust and can be installed via `rustup`: + +```bash +rustup target add riscv64im-unknown-none-elf +``` + +## Building Rust programs + +Build using the standard Cargo workflow: + +```bash +cargo build --target riscv64im-unknown-none-elf +``` + +You will need to provide a linker script. The [`riscv-rt`] crate handles this automatically when used as a dependency. + +## Testing + +This is a cross-compiled `no-std` target, which must be run either in a simulator or by programming onto suitable hardware. It is not possible to run the Rust test-suite on this target. + +You can test the target in QEMU with: + +```bash +qemu-system-riscv64 -machine virt -cpu rv64,a=false,c=false -nographic -semihosting -kernel your-binary +``` + +Note: You must explicitly disable the 'a' (atomics) and 'c' (compressed) extensions when using QEMU to accurately emulate an RV64IM-only CPU. + +## Cross-compilation toolchains and C code + +This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 9bae8b241a941..390ac722a3dba 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -152,6 +152,7 @@ static TARGETS: &[&str] = &[ "riscv32imac-unknown-none-elf", "riscv32imafc-unknown-none-elf", "riscv32gc-unknown-linux-gnu", + "riscv64im-unknown-none-elf", "riscv64imac-unknown-none-elf", "riscv64gc-unknown-hermit", "riscv64gc-unknown-none-elf", diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 4ca46013b5743..15ac8628a39de 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -517,6 +517,9 @@ //@ revisions: riscv64gc_unknown_redox //@ [riscv64gc_unknown_redox] compile-flags: --target riscv64gc-unknown-redox //@ [riscv64gc_unknown_redox] needs-llvm-components: riscv +//@ revisions: riscv64im_unknown_none_elf +//@ [riscv64im_unknown_none_elf] compile-flags: --target riscv64im-unknown-none-elf +//@ [riscv64im_unknown_none_elf] needs-llvm-components: riscv //@ revisions: riscv64imac_unknown_none_elf //@ [riscv64imac_unknown_none_elf] compile-flags: --target riscv64imac-unknown-none-elf //@ [riscv64imac_unknown_none_elf] needs-llvm-components: riscv From b8fc68212f63c3c05217f5ed18b2b444d0badd17 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 14:56:07 +0000 Subject: [PATCH 2/3] add riscv64im to ignore list for stage0 --- src/bootstrap/src/core/sanity.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed63b2aae452c..f4ce0596f6c4c 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -40,6 +40,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ "sparc64-unknown-helenos", // just a dummy comment so the list doesn't get onelined "riscv64gc-unknown-redox", + "riscv64im-unknown-none-elf", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM From 1281f26516475b3da86bda140e20684f8f839843 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 21:25:13 +0000 Subject: [PATCH 3/3] refactor readme --- .../riscv64im-unknown-none-elf.md | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md index 033904959db33..505810caa4254 100644 --- a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md @@ -12,7 +12,7 @@ Bare-metal target for RISC-V CPUs with the RV64IM ISA. This target is cross-compiled and uses static linking. The target supports `core` and `alloc`, but not `std`. -The target does not support atomic compare-and-swap operations, as the RV64IM ISA lacks the "A" (Atomics) extension. Atomic operations are emulated using the `+forced-atomics` feature. +As the RV64IM ISA lacks the "A" (Atomics) extension, atomic operations are emulated using the `+forced-atomics` feature. No external toolchain is required and the default `rust-lld` linker works, but you must specify a linker script. The [`riscv-rt`] crate provides suitable linker scripts. The [`riscv-rust-quickstart`] repository gives examples of RISC-V bare-metal projects. @@ -21,34 +21,27 @@ No external toolchain is required and the default `rust-lld` linker works, but y ## Building the target -This target is included in Rust and can be installed via `rustup`: +You can build Rust with support for the target by adding it to the `target` list in `bootstrap.toml`: -```bash -rustup target add riscv64im-unknown-none-elf +```toml +[build] +target = ["riscv64im-unknown-none-elf"] ``` -## Building Rust programs - -Build using the standard Cargo workflow: +Alternatively, you can use the `-Z build-std` flag to build the standard library on-demand: ```bash -cargo build --target riscv64im-unknown-none-elf +cargo build -Z build-std=core,alloc --target riscv64im-unknown-none-elf ``` -You will need to provide a linker script. The [`riscv-rt`] crate handles this automatically when used as a dependency. +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target (see "Building the target" above) ## Testing This is a cross-compiled `no-std` target, which must be run either in a simulator or by programming onto suitable hardware. It is not possible to run the Rust test-suite on this target. -You can test the target in QEMU with: - -```bash -qemu-system-riscv64 -machine virt -cpu rv64,a=false,c=false -nographic -semihosting -kernel your-binary -``` - -Note: You must explicitly disable the 'a' (atomics) and 'c' (compressed) extensions when using QEMU to accurately emulate an RV64IM-only CPU. - ## Cross-compilation toolchains and C code This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`.