Unify the arm*-none-* and thumb*-none-* target descriptions.

This commit is contained in:
Jonathan 'theJPster' Pallant 2025-11-16 20:20:44 +00:00
parent 38987c0b9a
commit dbcb048e28
No known key found for this signature in database
25 changed files with 37 additions and 172 deletions

View file

@ -1,31 +1,4 @@
// These `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
// microcontrollers. Namely, all these processors:
//
// - Cortex-M0
// - Cortex-M0+
// - Cortex-M1
// - Cortex-M3
// - Cortex-M4(F)
// - Cortex-M7(F)
// - Cortex-M23
// - Cortex-M33
//
// We have opted for these instead of one target per processor (e.g., `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
// nonexistent from the POV of codegen so it doesn't make sense to have separate targets for them.
// And if differences exist between two processors under the same target, rustc flags can be used to
// optimize for one processor or the other.
//
// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
// differentiate one processor from the other.
//
// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
// triples use thumb instead of arm. We follow suit because having thumb in the name let us
// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags.
// These are the baseline settings for 32-bit bare-metal Arm targets using the EABI or EABIHF ABI.
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions};

View file

@ -1,6 +1,7 @@
pub(crate) mod aix;
pub(crate) mod android;
pub mod apple;
pub(crate) mod arm_none;
pub(crate) mod avr;
pub(crate) mod bpf;
pub(crate) mod cygwin;
@ -31,7 +32,6 @@ pub(crate) mod redox;
pub(crate) mod solaris;
pub(crate) mod solid;
pub(crate) mod teeos;
pub(crate) mod thumb;
pub(crate) mod uefi_msvc;
pub(crate) mod unikraft_linux_musl;
pub(crate) mod vxworks;

View file

@ -9,10 +9,7 @@
//! The default link script is very likely wrong, so you should use
//! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script.
use crate::spec::{
Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata,
TargetOptions, cvs,
};
use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs};
pub(crate) fn target() -> Target {
Target {
@ -29,36 +26,11 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
// Force-enable 32-bit atomics, which allows the use of atomic load/store only.
// The resulting atomics are ABI incompatible with atomics backed by libatomic.
features: "+soft-float,+strict-align".into(),
atomic_cas: false,
has_thumb_interworking: true,
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
// Because these devices have very little resources having an unwinder is too onerous so we
// default to "abort" because the "unwind" strategy is very rare.
panic_strategy: PanicStrategy::Abort,
// Similarly, one almost always never wants to use relocatable code because of the extra
// costs it involves.
relocation_model: RelocModel::Static,
// When this section is added a volatile load to its start address is also generated. This
// volatile load is a footgun as it can end up loading an invalid memory address, depending
// on how the user set up their linker scripts. This section adds pretty printer for stuff
// like std::Vec, which is not that used in no-std context, so it's best to left it out
// until we figure a way to add the pretty printers without requiring a volatile load cf.
// rust-lang/rust#44993.
emit_debug_gdb_scripts: false,
// LLVM is eager to trash the link register when calling `noreturn` functions, which
// breaks debugging. Preserve LR by default to prevent that from happening.
frame_pointer: FramePointer::Always,
// ARM supports multiple ABIs for enums, the linux one matches the default of 32 here
// but any arm-none or thumb-none target will be defaulted to 8 on GCC.
c_enum_min_bits: Some(8),
..Default::default()
..base::arm_none::opts()
},
}
}

View file

@ -1,8 +1,6 @@
//! Targets the ARMv5TE, with code as `a32` code by default.
use crate::spec::{
Abi, Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs,
};
use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs};
pub(crate) fn target() -> Target {
Target {
@ -19,37 +17,11 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
// extra args passed to the external assembler (assuming `arm-none-eabi-as`):
// * activate t32/a32 interworking
// * use arch ARMv5TE
// * use little-endian
asm_args: cvs!["-mthumb-interwork", "-march=armv5te", "-mlittle-endian",],
// minimum extra features, these cannot be disabled via -C
features: "+soft-float,+strict-align".into(),
atomic_cas: false,
has_thumb_interworking: true,
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
// Because these devices have very little resources having an unwinder is too onerous so we
// default to "abort" because the "unwind" strategy is very rare.
panic_strategy: PanicStrategy::Abort,
// Similarly, one almost always never wants to use relocatable code because of the extra
// costs it involves.
relocation_model: RelocModel::Static,
// When this section is added a volatile load to its start address is also generated. This
// volatile load is a footgun as it can end up loading an invalid memory address, depending
// on how the user set up their linker scripts. This section adds pretty printer for stuff
// like std::Vec, which is not that used in no-std context, so it's best to left it out
// until we figure a way to add the pretty printers without requiring a volatile load cf.
// rust-lang/rust#44993.
emit_debug_gdb_scripts: false,
// LLVM is eager to trash the link register when calling `noreturn` functions, which
// breaks debugging. Preserve LR by default to prevent that from happening.
frame_pointer: FramePointer::Always,
// ARM supports multiple ABIs for enums, the linux one matches the default of 32 here
// but any arm-none or thumb-none target will be defaulted to 8 on GCC.
c_enum_min_bits: Some(8),
..Default::default()
..base::arm_none::opts()
},
}
}

View file

@ -9,10 +9,7 @@
//! The default link script is very likely wrong, so you should use
//! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script.
use crate::spec::{
Abi, Arch, FloatAbi, FramePointer, PanicStrategy, RelocModel, Target, TargetMetadata,
TargetOptions, base, cvs,
};
use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs};
pub(crate) fn target() -> Target {
Target {
@ -25,44 +22,15 @@ pub(crate) fn target() -> Target {
},
pointer_width: 32,
arch: Arch::Arm,
/* Data layout args are '-' separated:
* little endian
* stack is 64-bit aligned (EABI)
* pointers are 32-bit
* i64 must be 64-bit aligned (EABI)
* mangle names with ELF style
* native integers are 32-bit
* All other elements are default
*/
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
options: TargetOptions {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
// extra args passed to the external assembler (assuming `arm-none-eabi-as`):
// * activate t32/a32 interworking
// * use arch ARMv4T
// * use little-endian
asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
// minimum extra features, these cannot be disabled via -C
// Also force-enable 32-bit atomics, which allows the use of atomic load/store only.
// The resulting atomics are ABI incompatible with atomics backed by libatomic.
features: "+soft-float,+strict-align,+atomics-32".into(),
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
// suggested from thumb_base, rust-lang/rust#44993.
emit_debug_gdb_scripts: false,
frame_pointer: FramePointer::MayOmit,
main_needs_argc_argv: false,
// don't have atomic compare-and-swap
features: "+soft-float,+strict-align".into(),
atomic_cas: false,
has_thumb_interworking: true,
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -1,8 +1,6 @@
//! Targets the ARMv5TE, with code as `t32` code by default.
use crate::spec::{
Abi, Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs,
};
use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs};
pub(crate) fn target() -> Target {
Target {
@ -15,36 +13,15 @@ pub(crate) fn target() -> Target {
},
pointer_width: 32,
arch: Arch::Arm,
/* Data layout args are '-' separated:
* little endian
* stack is 64-bit aligned (EABI)
* pointers are 32-bit
* i64 must be 64-bit aligned (EABI)
* mangle names with ELF style
* native integers are 32-bit
* All other elements are default
*/
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
options: TargetOptions {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
// extra args passed to the external assembler (assuming `arm-none-eabi-as`):
// * activate t32/a32 interworking
// * use arch ARMv5TE
// * use little-endian
asm_args: cvs!["-mthumb-interwork", "-march=armv5te", "-mlittle-endian",],
// minimum extra features, these cannot be disabled via -C
// Also force-enable 32-bit atomics, which allows the use of atomic load/store only.
// The resulting atomics are ABI incompatible with atomics backed by libatomic.
features: "+soft-float,+strict-align,+atomics-32".into(),
frame_pointer: FramePointer::MayOmit,
main_needs_argc_argv: false,
// don't have atomic compare-and-swap
features: "+soft-float,+strict-align".into(),
atomic_cas: false,
has_thumb_interworking: true,
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -26,7 +26,7 @@ pub(crate) fn target() -> Target {
// There are no atomic CAS instructions available in the instruction set of the ARMv6-M
// architecture
atomic_cas: false,
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -25,7 +25,7 @@ pub(crate) fn target() -> Target {
// The ARMv6-M doesn't support hardware atomic operations, use atomic builtins instead.
features: "+strict-align".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -27,7 +27,7 @@ pub(crate) fn target() -> Target {
// Cortex-A7/A8/A9 with software floating point
features: "+soft-float,-neon".into(),
max_atomic_width: Some(64),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -31,7 +31,7 @@ pub(crate) fn target() -> Target {
// and NEON SIMD instructions
features: "+vfp3,+neon".into(),
max_atomic_width: Some(64),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -28,7 +28,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -36,7 +36,7 @@ pub(crate) fn target() -> Target {
// ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
features: "+vfp4d16sp".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -30,7 +30,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -38,7 +38,7 @@ pub(crate) fn target() -> Target {
// ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
features: "+vfp4d16sp".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -21,7 +21,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
// with +strict-align.
features: "+strict-align".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -24,7 +24,7 @@ pub(crate) fn target() -> Target {
// with +strict-align.
features: "+strict-align".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -20,7 +20,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -25,7 +25,7 @@ pub(crate) fn target() -> Target {
// and 16 D registers.
features: "+fp-armv8d16sp".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
abi: Abi::Eabi,
llvm_floatabi: Some(FloatAbi::Soft),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -27,7 +27,7 @@ pub(crate) fn target() -> Target {
// and 16 D registers.
features: "+fp-armv8d16sp".into(),
max_atomic_width: Some(32),
..base::thumb::opts()
..base::arm_none::opts()
},
}
}

View file

@ -54,8 +54,8 @@
- [aarch64_be-unknown-linux-musl](platform-support/aarch64_be-unknown-linux-musl.md)
- [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
- [arm-none-eabi](platform-support/arm-none-eabi.md)
- [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
- [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
- [{arm,thumb}v4t-none-eabi](platform-support/armv4t-none-eabi.md)
- [{arm,thumb}v5te-none-eabi](platform-support/armv5te-none-eabi.md)
- [armv7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md)
- [armv7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md)
- [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md)

View file

@ -8,7 +8,8 @@ group, and all the information there applies.
Both of these targets can be used on the Game Boy Advance (GBA), among other
things. On the GBA, one should usually use the `thumb` target to get the best
overall performance.
overall performance. Note that this architecture only supports the old
Thumb-1 instruction set, not the later Thumb-2 instruction set.
## Target Maintainers

View file

@ -4,10 +4,12 @@
* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
Bare-metal target for any cpu in the Armv5TE architecture family, supporting
ARM/Thumb code interworking (aka `A32`/`T32`), with `A32` code as the default code
generation.
ARM/Thumb code interworking (aka `Arm`/`Thumb`), with `Arm` code as the
default code generation.
The `thumbv5te-none-eabi` target is the same as this one, but the instruction set defaults to `T32`.
The `thumbv5te-none-eabi` target is the same as this one, but the instruction
set defaults to `Thumb`. Note that this architecture only supports the old
Thumb-1 instruction set, not the later Thumb-2 instruction set.
See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
`arm-none-eabi` targets.