diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4a82a8bd888e6..e58646d741486 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-qurt", hexagon_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_qurt.rs b/compiler/rustc_target/src/spec/targets/hexagon_qurt.rs new file mode 100644 index 0000000000000..7f153fa683bbe --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/hexagon_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 eaa9e3a6a3e9d..f7a6f937246c7 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -35,6 +35,7 @@ pub struct Finder { const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "x86_64-unknown-motor", + "hexagon-unknown-qurt", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d0b6ed51bc163..c95229e591930 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -314,6 +314,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.3 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) +[`hexagon-qurt`](platform-support/hexagon-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..f2053e685d54d --- /dev/null +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-qurt.md @@ -0,0 +1,174 @@ +# `hexagon-qurt` + +**Tier: 3** + +Rust for Hexagon QuRT (Qualcomm Real-Time OS). + +| Target | Description | +| -------------------- | ------------| +| hexagon-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-qurt"] + +[target.hexagon-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-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-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-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-qurt] +rustflags = [ + "-C", "link-args=-shared", + "-C", "link-args=-fPIC", + "-C", "relocation-model=pic" +] +``` + +## Testing + +Since `hexagon-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 +} +``` + +```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 ebea9fe40f518..a4d6e5e61d8a9 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -232,6 +232,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_qurt +//@ [hexagon_qurt] compile-flags: --target hexagon-qurt +//@ [hexagon_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 39fee52a909b6..612f227b92aff 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`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, and `trusty` and 12 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, and `teeos` and 13 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 e62f741b3020c..fc1c0b2016ce0 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`, `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`, `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`, `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`, `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