Skip to content

Add minimal armv7a-vex-v5 tier three target #145070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion compiler/rustc_target/src/spec/abi_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,15 @@ impl AbiMap {
"x86_64" => Arch::X86_64,
_ => Arch::Other,
};
let os = if target.is_like_windows { OsKind::Windows } else { OsKind::Other };

let os = if target.is_like_windows {
OsKind::Windows
} else if target.is_like_vexos {
OsKind::VEXos
} else {
OsKind::Other
};

AbiMap { arch, os }
}

Expand All @@ -82,6 +90,10 @@ impl AbiMap {
(ExternAbi::System { .. }, Arch::X86) if os == OsKind::Windows && !has_c_varargs => {
CanonAbi::X86(X86Call::Stdcall)
}
(ExternAbi::System { .. }, Arch::Arm(..)) if self.os == OsKind::VEXos => {
// Calls to VEXos APIs do not use VFP registers.
CanonAbi::Arm(ArmCall::Aapcs)
}
(ExternAbi::System { .. }, _) => CanonAbi::C,

// fallible lowerings
Expand Down Expand Up @@ -191,6 +203,7 @@ enum Arch {
#[derive(Debug, PartialEq, Copy, Clone)]
enum OsKind {
Windows,
VEXos,
Other,
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl Target {
forward!(is_like_msvc);
forward!(is_like_wasm);
forward!(is_like_android);
forward!(is_like_vexos);
forward!(binary_format);
forward!(default_dwarf_version);
forward!(allows_weak_linkage);
Expand Down Expand Up @@ -345,6 +346,7 @@ impl ToJson for Target {
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(is_like_android);
target_option_val!(is_like_vexos);
target_option_val!(binary_format);
target_option_val!(default_dwarf_version);
target_option_val!(allows_weak_linkage);
Expand Down Expand Up @@ -538,6 +540,7 @@ struct TargetSpecJson {
is_like_msvc: Option<bool>,
is_like_wasm: Option<bool>,
is_like_android: Option<bool>,
is_like_vexos: Option<bool>,
binary_format: Option<BinaryFormat>,
default_dwarf_version: Option<u32>,
allows_weak_linkage: Option<bool>,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2101,6 +2101,7 @@ supported_targets! {
("armv7a-none-eabihf", armv7a_none_eabihf),
("armv7a-nuttx-eabi", armv7a_nuttx_eabi),
("armv7a-nuttx-eabihf", armv7a_nuttx_eabihf),
("armv7a-vex-v5", armv7a_vex_v5),

("msp430-none-elf", msp430_none_elf),

Expand Down Expand Up @@ -2571,6 +2572,8 @@ pub struct TargetOptions {
pub is_like_wasm: bool,
/// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc
pub is_like_android: bool,
/// Whether a target toolchain is like VEXos, the operating system used by the VEX Robotics V5 Brain.
pub is_like_vexos: bool,
/// Target's binary file format. Defaults to BinaryFormat::Elf
pub binary_format: BinaryFormat,
/// Default supported version of DWARF on this platform.
Expand Down Expand Up @@ -2953,6 +2956,7 @@ impl Default for TargetOptions {
is_like_msvc: false,
is_like_wasm: false,
is_like_android: false,
is_like_vexos: false,
binary_format: BinaryFormat::Elf,
default_dwarf_version: 4,
allows_weak_linkage: true,
Expand Down
44 changes: 44 additions & 0 deletions compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::spec::{
Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata,
TargetOptions,
};

const LINKER_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld");

pub(crate) fn target() -> Target {
let opts = TargetOptions {
vendor: "vex".into(),
env: "v5".into(),
os: "vexos".into(),
cpu: "cortex-a9".into(),
abi: "eabihf".into(),
is_like_vexos: true,
llvm_floatabi: Some(FloatAbi::Hard),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
features: "+v7,+neon,+vfp3d16,+thumb2".into(),
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(64),
panic_strategy: PanicStrategy::Abort,
emit_debug_gdb_scripts: false,
c_enum_min_bits: Some(8),
default_uwtable: true,
has_thumb_interworking: true,
link_script: Some(LINKER_SCRIPT.into()),
..Default::default()
};
Target {
llvm_target: "armv7a-none-eabihf".into(),
metadata: TargetMetadata {
description: Some("ARMv7-A Cortex-A9 VEX V5 Brain".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),
options: opts,
}
}
144 changes: 144 additions & 0 deletions compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
OUTPUT_FORMAT("elf32-littlearm")
ENTRY(_boot)

/*
* PROVIDE() is used here so that users can override default values.
* This is intended to give developers the option to use this Rust
* target even if the default values in this linker script aren't
* suitable for their needs.
*
* For example: `-C link-arg=--defsym=__stack_length=8M` could
* be used to increase the stack size above the value set in this
* file.
*/

PROVIDE(__vcodesig_magic = 0x35585658); /* XVX5 */
PROVIDE(__vcodesig_type = 0); /* V5_SIG_TYPE_USER */
PROVIDE(__vcodesig_owner = 2); /* V5_SIG_OWNER_PARTNER */
PROVIDE(__vcodesig_options = 0); /* none (0) */

PROVIDE(__user_ram_start = 0x03800000);
PROVIDE(__user_ram_length = 48M);
PROVIDE(__user_ram_end = __user_ram_start + __user_ram_length); /* 0x8000000 */

PROVIDE(__code_signature_length = 0x20);

PROVIDE(__stack_length = 4M);
PROVIDE(__heap_end = __user_ram_end - __stack_length);
PROVIDE(__user_length = __heap_start - __user_ram_start);

MEMORY {
USER_RAM (RWX) : ORIGIN = __user_ram_start, LENGTH = __user_ram_length
}

SECTIONS {
/*
* VEXos expects program binaries to have a 32-byte header called a "code signature"
* at their start which tells the OS that we are a valid program and configures some
* miscellaneous startup behavior.
*/
.code_signature : {
LONG(__vcodesig_magic)
LONG(__vcodesig_type)
LONG(__vcodesig_owner)
LONG(__vcodesig_options)

FILL(0)
. = __user_ram_start + __code_signature_length;
} > USER_RAM

/*
* Executable program instructions.
*/
.text : {
/* _boot routine (entry point from VEXos, must be at 0x03800020) */
*(.boot)

/* The rest of the program. */
*(.text .text.*)
} > USER_RAM

/*
* Global/uninitialized/static/constant data sections.
*/
.rodata : {
*(.rodata .rodata1 .rodata.*)
*(.srodata .srodata.*)
} > USER_RAM

/*
* ARM Stack Unwinding Sections
*
* These sections are added by the compiler in some cases to facilitate stack unwinding.
* __eh_frame_start and similar symbols are used by libunwind.
*/

.except_ordered : {
PROVIDE(__extab_start = .);
*(.gcc_except_table *.gcc_except_table.*)
*(.ARM.extab*)
PROVIDE(__extab_end = .);
} > USER_RAM

.eh_frame_hdr : {
/* see https://github.com/llvm/llvm-project/blob/main/libunwind/src/AddressSpace.hpp#L78 */
PROVIDE(__eh_frame_hdr_start = .);
KEEP(*(.eh_frame_hdr))
PROVIDE(__eh_frame_hdr_end = .);
} > USER_RAM

.eh_frame : {
PROVIDE(__eh_frame_start = .);
KEEP(*(.eh_frame))
PROVIDE(__eh_frame_end = .);
} > USER_RAM

.except_unordered : {
PROVIDE(__exidx_start = .);
*(.ARM.exidx*)
PROVIDE(__exidx_end = .);
} > USER_RAM

/* -- Data intended to be mutable at runtime begins here. -- */

.data : {
*(.data .data1 .data.*)
*(.sdata .sdata.* .sdata2.*)
} > USER_RAM

/* -- End of loadable sections - anything beyond this point shouldn't go in the binary uploaded to the device. -- */

.bss (NOLOAD) : {
__bss_start = .;
*(.sbss*)
*(.bss .bss.*)

/* Align the heap */
. = ALIGN(8);
__bss_end = .;
} > USER_RAM

/*
* Active memory sections for the stack/heap.
*
* Because these are (NOLOAD), they will not influence the final size of the binary.
*/
.heap (NOLOAD) : {
__heap_start = .;
. = __heap_end;
} > USER_RAM

.stack (NOLOAD) : ALIGN(8) {
__stack_bottom = .;
. += __stack_length;
__stack_top = .;
} > USER_RAM

/*
* `.ARM.attributes` contains arch metadata for compatibility purposes, but we
* only target one hardware configuration, meaning it'd just take up space.
*/
/DISCARD/ : {
*(.ARM.attributes*)
}
}
1 change: 1 addition & 0 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct Finder {
//
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
const STAGE0_MISSING_TARGETS: &[&str] = &[
"armv7a-vex-v5",
// just a dummy comment so the list doesn't get onelined
];

Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
- [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
- [armv7a-vex-v5](platform-support/armv7a-vex-v5.md)
- [\*-android and \*-androideabi](platform-support/android.md)
- [\*-linux-ohos](platform-support/openharmony.md)
- [\*-hurd-gnu](platform-support/hurd.md)
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ target | std | host | notes
[`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3
[`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat
[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * | | Bare Armv7-A, hardfloat
[`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | ? | | Armv7-A Cortex-A9 VEX V5 Brain, VEXos
[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS
[`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS
[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat
Expand Down
83 changes: 83 additions & 0 deletions src/doc/rustc/src/platform-support/armv7a-vex-v5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# `armv7a-vex-v5`

**Tier: 3**

Allows compiling user programs for the [VEX V5 Brain](https://www.vexrobotics.com/276-4810.html), a microcontroller for educational and competitive robotics.

Rust support for this target is not affiliated with VEX Robotics or IFI.

## Target maintainers

This target is maintained by members of the [vexide](https://github.com/vexide) organization:

- [@lewisfm](https://github.com/lewisfm)
- [@Tropix126](https://github.com/Tropix126)
- [@Gavin-Niederman](https://github.com/Gavin-Niederman)
- [@max-niederman](https://github.com/max-niederman)

## Requirements

This target is cross-compiled and currently requires `#![no_std]`. Dynamic linking is unsupported.

When compiling for this target, the "C" calling convention maps to AAPCS with VFP registers (hard float ABI) and the "system" calling convention maps to AAPCS without VFP registers (soft float ABI).

This target generates binaries in the ELF format that may uploaded to the brain with external tools.

## Building the target

You can build Rust with support for this target by adding it to the `target` list in `bootstrap.toml`, and then running `./x build --target armv7a-vex-v5 compiler`.

## 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.

When the compiler builds a binary, an ELF build artifact will be produced. Additional tools are required for this artifact to be recognizable to VEXos as a user program.

The [cargo-v5](https://github.com/vexide/cargo-v5) tool is capable of creating binaries that can be uploaded to the V5 brain. This tool wraps the `cargo build` command by supplying arguments necessary to build the target and produce an artifact recognizable to VEXos, while also providing functionality for uploading over USB to a V5 Controller or Brain.

To install the tool, run:

```sh
cargo install cargo-v5
```

The following fields in your project's `Cargo.toml` are read by `cargo-v5` to configure upload behavior:

```toml
[package.metadata.v5]
# Slot number to upload the user program to. This should be from 1-8.
slot = 1
# Program icon/thumbnail that will be displayed on the dashboard.
icon = "cool-x"
# Use gzip compression when uploading binaries.
compress = true
```

To build an uploadable BIN file using the release profile, run:

```sh
cargo v5 build --release
```

Programs can also be directly uploaded to the brain over a USB connection immediately after building:

```sh
cargo v5 upload --release
```

## Testing

Binaries built for this target can be run in an emulator (such as [vex-v5-qemu](https://github.com/vexide/vex-v5-qemu)), or uploaded to a physical device over a serial (USB) connection.

The default Rust test runner is not supported.

The Rust test suite for `library/std` is not yet supported.

## Cross-compilation toolchains and C code

This target can be cross-compiled from any host.

Linking to C libraries is not supported.
3 changes: 3 additions & 0 deletions tests/assembly-llvm/targets/targets-elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@
//@ revisions: armv7a_nuttx_eabihf
//@ [armv7a_nuttx_eabihf] compile-flags: --target armv7a-nuttx-eabihf
//@ [armv7a_nuttx_eabihf] needs-llvm-components: arm
//@ revisions: armv7a_vex_v5
//@ [armv7a_vex_v5] compile-flags: --target armv7a-vex-v5
//@ [armv7a_vex_v5] needs-llvm-components: arm
//@ revisions: armv7r_none_eabi
//@ [armv7r_none_eabi] compile-flags: --target armv7r-none-eabi
//@ [armv7r_none_eabi] needs-llvm-components: arm
Expand Down
Loading
Loading