diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b49e7fc9cff66..f97cc2666ab86 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1487,6 +1487,7 @@ supported_targets! { ("mips64el-unknown-linux-muslabi64", mips64el_unknown_linux_muslabi64), ("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl), ("hexagon-unknown-none-elf", hexagon_unknown_none_elf), + ("hexagon-unknown-qurt", hexagon_unknown_qurt), ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc), ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc), diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_qurt.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_qurt.rs new file mode 100644 index 0000000000000..7f153fa683bbe --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_qurt.rs @@ -0,0 +1,46 @@ +use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, TargetOptions, cvs}; + +pub(crate) fn target() -> Target { + let mut pre_link_args = std::collections::BTreeMap::>::new(); + pre_link_args.entry(LinkerFlavor::Unix(Cc::Yes)).or_default().extend(["-G0".into()]); + + Target { + llvm_target: "hexagon-unknown-elf".into(), + metadata: TargetMetadata { + description: Some("Hexagon QuRT".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "\ + e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32\ + :32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32\ + :32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048\ + :2048:2048" + .into(), + arch: "hexagon".into(), + options: TargetOptions { + os: "qurt".into(), + vendor: "unknown".into(), + cpu: "hexagonv69".into(), + linker: Some("rust-lld".into()), + linker_flavor: LinkerFlavor::Unix(Cc::Yes), + exe_suffix: ".elf".into(), + dynamic_linking: true, + executables: true, + families: cvs!["unix"], + has_thread_local: true, + has_rpath: false, + crt_static_default: false, + crt_static_respected: true, + crt_static_allows_dylibs: true, + no_default_libraries: false, + max_atomic_width: Some(32), + features: "-small-data,+hvx-length128b".into(), + c_enum_min_bits: Some(8), + pre_link_args, + ..Default::default() + }, + } +} diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed63b2aae452c..bcd5c62b675b3 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", + "hexagon-unknown-qurt", ]; /// 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..4cf95a04465a6 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -87,6 +87,7 @@ - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) - [hexagon-unknown-none-elf](platform-support/hexagon-unknown-none-elf.md) + - [hexagon-unknown-qurt](platform-support/hexagon-unknown-qurt.md) - [illumos](platform-support/illumos.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 0827d3d9319c5..dd23584d9e0c0 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -315,6 +315,7 @@ target | std | host | notes `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.5 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) +[`hexagon-unknown-qurt`](platform-support/hexagon-unknown-qurt.md)| * | | Hexagon QuRT [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] [`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-qurt.md b/src/doc/rustc/src/platform-support/hexagon-unknown-qurt.md new file mode 100644 index 0000000000000..7928804d09545 --- /dev/null +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-qurt.md @@ -0,0 +1,180 @@ +# `hexagon-unknown-qurt` + +**Tier: 3** + +Rust for Hexagon QuRT (Qualcomm Real-Time OS). + +| Target | Description | +| -------------------- | ------------| +| hexagon-unknown-qurt | Hexagon 32-bit QuRT | + +## Target maintainers + +[@androm3da](https://github.com/androm3da) + +## Requirements + +This target is cross-compiled. There is support for `std`. The target uses +QuRT's standard library and runtime. + +By default, code generated with this target should run on Hexagon DSP hardware +running the QuRT real-time operating system. + +- `-Ctarget-cpu=hexagonv69` targets Hexagon V69 architecture (default) +- `-Ctarget-cpu=hexagonv73` adds support for instructions defined up to Hexagon V73 + +Functions marked `extern "C"` use the [Hexagon architecture calling convention](https://lists.llvm.org/pipermail/llvm-dev/attachments/20190916/21516a52/attachment-0001.pdf). + +This target generates position-independent ELF binaries by default, making it +suitable for both static images and dynamic shared objects. + +The [Hexagon SDK](https://softwarecenter.qualcomm.com/catalog/item/Hexagon_SDK) is +required for building programs for this target. + +## Linking + +This target selects `rust-lld` by default. Another option to use is +[eld](https://github.com/qualcomm/eld), which is also provided with +[the opensource hexagon toolchain](https://github.com/quic/toolchain_for_hexagon) +and the Hexagon SDK. + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `bootstrap.toml`: + +```toml +[build] +build-stage = 1 +host = [""] +target = ["", "hexagon-unknown-qurt"] + +[target.hexagon-unknown-qurt] +cc = "hexagon-clang" +cxx = "hexagon-clang++" +ranlib = "llvm-ranlib" +ar = "llvm-ar" +llvm-libunwind = 'in-tree' +``` + +Replace `` with `x86_64-unknown-linux-gnu` or whatever +else is appropriate for your host machine. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Static Image Targeting + +For static executables that run directly on QuRT, use the default target +configuration with additional linker flags: + +```sh +# Build a static executable for QuRT +cargo rustc --target hexagon-unknown-qurt -- \ + -C link-args="-static -nostdlib" \ + -C link-args="-L/opt/Hexagon_SDK/6.3.0.0/rtos/qurt/computev69/lib" \ + -C link-args="-lqurt -lc" +``` + +This approach is suitable for: +- Standalone QuRT applications +- System-level services +- Boot-time initialization code +- Applications that need deterministic memory layout + +## User-Loadable Shared Object Targeting + +For shared libraries that can be dynamically loaded by QuRT applications: + +```sh +# Build a shared object for QuRT +cargo rustc --target hexagon-unknown-qurt \ + --crate-type=cdylib -- \ + -C link-args="-shared -fPIC" \ + -C link-args="-L/opt/Hexagon_SDK/6.3.0.0/rtos/qurt/computev69/lib" +``` + +This approach is suitable for: +- Plugin architectures +- Runtime-loadable modules +- Libraries shared between multiple applications +- Code that needs to be updated without system restart + +## Configuration Options + +The target can be customized for different use cases: + +### For Static Images +```toml +# In .cargo/config.toml +[target.hexagon-unknown-qurt] +rustflags = [ + "-C", "link-args=-static", + "-C", "link-args=-nostdlib", + "-C", "target-feature=-small-data" +] +``` + +### For Shared Objects +```toml +# In .cargo/config.toml +[target.hexagon-unknown-qurt] +rustflags = [ + "-C", "link-args=-shared", + "-C", "link-args=-fPIC", + "-C", "relocation-model=pic" +] +``` + +## Testing + +Since `hexagon-unknown-qurt` requires the QuRT runtime environment, testing requires +either: +- Hexagon hardware with QuRT +- `hexagon-sim` +- QEMU (`qemu-system-hexagon`) + +## Cross-compilation toolchains and C code + +This target requires the proprietary [Hexagon SDK toolchain for C interoperability](https://softwarecenter.qualcomm.com/catalog/item/Hexagon_SDK): + +- **Sample SDK Path**: `/opt/Hexagon_SDK/6.3.0.0/` +- **Toolchain**: Use `hexagon-clang` from the Hexagon SDK +- **Libraries**: Link against QuRT system libraries as needed + +### C Interoperability Example + +```rust +// lib.rs +#![no_std] +extern crate std; + +#[unsafe(no_mangle)] +pub extern "C" fn rust_function() -> i32 { + // Your Rust code here + 42 +} + +fn main() { + // Example usage + let result = rust_function(); + assert_eq!(result, 42); +} +``` + +```c +// wrapper.c +extern int rust_function(void); + +int main() { + return rust_function(); +} +``` + +The target supports both static linking for standalone applications and dynamic +linking for modular architectures, making it flexible for various QuRT +deployment scenarios. diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index d2f22fd8d1a50..8727d4dceaf70 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -235,6 +235,9 @@ //@ revisions: hexagon_unknown_none_elf //@ [hexagon_unknown_none_elf] compile-flags: --target hexagon-unknown-none-elf //@ [hexagon_unknown_none_elf] needs-llvm-components: hexagon +//@ revisions: hexagon_unknown_qurt +//@ [hexagon_unknown_qurt] compile-flags: --target hexagon-unknown-qurt +//@ [hexagon_unknown_qurt] needs-llvm-components: hexagon //@ revisions: i686_pc_nto_qnx700 //@ [i686_pc_nto_qnx700] compile-flags: --target i686-pc-nto-qnx700 //@ [i686_pc_nto_qnx700] needs-llvm-components: x86 diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr index 38301f470bf73..242883995488e 100644 --- a/tests/ui/check-cfg/cfg-crate-features.stderr +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist` LL | #![cfg(not(target(os = "does_not_exist")))] | ^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, and `teeos` and 13 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, and `solid_asp3` and 14 more = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 8205756d64dd1..87c2d335f8012 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 28 warnings emitted