From cbc56f16b48f4d7ae9a77be4b9b51a5212c8b435 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 3 Oct 2016 22:28:40 -0500 Subject: [PATCH] add +d16 and +fp-only-sp to thumbv7em-none-eabihf and documentation --- src/librustc_back/target/thumb_base.rs | 34 +++++++++++++++++++ .../target/thumbv6m_none_eabi.rs | 2 ++ .../target/thumbv7em_none_eabi.rs | 11 ++++++ .../target/thumbv7em_none_eabihf.rs | 19 +++++++++-- .../target/thumbv7m_none_eabi.rs | 2 ++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/thumb_base.rs b/src/librustc_back/target/thumb_base.rs index 14fa37b0c29d..61be7ff2f5d1 100644 --- a/src/librustc_back/target/thumb_base.rs +++ b/src/librustc_back/target/thumb_base.rs @@ -8,14 +8,48 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// These 4 `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) +// +// We have opted for 4 targets 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 +// non-existent 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. + use target::TargetOptions; use std::default::Default; pub fn opts() -> TargetOptions { + // See rust-lang/rfcs#1645 for a discussion about these defaults TargetOptions { executables: true, + // In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many + // options around) linker: "arm-none-eabi-gcc".to_string(), + // 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: "abort".to_string(), + // Similarly, one almost always never wants to use relocatable code because of the extra + // costs it involves. relocation_model: "static".to_string(), .. Default::default() } diff --git a/src/librustc_back/target/thumbv6m_none_eabi.rs b/src/librustc_back/target/thumbv6m_none_eabi.rs index 0163c2807ee6..d00744353a64 100644 --- a/src/librustc_back/target/thumbv6m_none_eabi.rs +++ b/src/librustc_back/target/thumbv6m_none_eabi.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) + use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/thumbv7em_none_eabi.rs b/src/librustc_back/target/thumbv7em_none_eabi.rs index f0b71e564167..6f5216e0f776 100644 --- a/src/librustc_back/target/thumbv7em_none_eabi.rs +++ b/src/librustc_back/target/thumbv7em_none_eabi.rs @@ -8,6 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Targets the Cortex-M4 and Cortex-M7 processors (ARMv7E-M) +// +// This target assumes that the device doesn't have a FPU (Floating Point Unit) and lowers all the +// floating point operations to software routines (intrinsics). +// +// As such, this target uses the "soft" calling convention (ABI) where floating point values are +// passed to/from subroutines via general purpose registers (R0, R1, etc.). +// +// To opt-in to hardware accelerated floating point operations, you can use, for example, +// `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. + use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { diff --git a/src/librustc_back/target/thumbv7em_none_eabihf.rs b/src/librustc_back/target/thumbv7em_none_eabihf.rs index f0ae96259f0a..74bb9915e68e 100644 --- a/src/librustc_back/target/thumbv7em_none_eabihf.rs +++ b/src/librustc_back/target/thumbv7em_none_eabihf.rs @@ -8,6 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Targets the Cortex-M4F and Cortex-M7F processors (ARMv7E-M) +// +// This target assumes that the device does have a FPU (Floating Point Unit) and lowers all (single +// precision) floating point operations to hardware instructions. +// +// Additionally, this target uses the "hard" floating convention (ABI) where floating point values +// are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.). +// +// To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag. + use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -22,8 +32,13 @@ pub fn target() -> TargetResult { target_vendor: "".to_string(), options: TargetOptions { - // vfp4 lowest common denominator between the Cortex-M4 (vfp4) and the Cortex-M7 (vfp5) - features: "+vfp4".to_string(), + // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the + // Cortex-M7 (vfp5) + // `+d16` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers + // available + // `+fp-only-sp` The Cortex-M4 only supports single precision floating point operations + // whereas in the Cortex-M7 double precision is optional + features: "+vfp4,+d16,+fp-only-sp".to_string(), max_atomic_width: 32, .. super::thumb_base::opts() } diff --git a/src/librustc_back/target/thumbv7m_none_eabi.rs b/src/librustc_back/target/thumbv7m_none_eabi.rs index de97ef1b641d..1ff95e1080b4 100644 --- a/src/librustc_back/target/thumbv7m_none_eabi.rs +++ b/src/librustc_back/target/thumbv7m_none_eabi.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Targets the Cortex-M3 processor (ARMv7-M) + use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult {