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/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 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..505810caa4254 --- /dev/null +++ b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md @@ -0,0 +1,47 @@ +# `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`. + +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 + +You can build Rust with support for the target by adding it to the `target` list in `bootstrap.toml`: + +```toml +[build] +target = ["riscv64im-unknown-none-elf"] +``` + +Alternatively, you can use the `-Z build-std` flag to build the standard library on-demand: + +```bash +cargo build -Z build-std=core,alloc --target riscv64im-unknown-none-elf +``` + +## 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. + +## 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