]>
Commit | Line | Data |
---|---|---|
a1dfa0c6 | 1 | // These `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in |
c30ab7b3 SL |
2 | // microcontrollers. Namely, all these processors: |
3 | // | |
4 | // - Cortex-M0 | |
5 | // - Cortex-M0+ | |
6 | // - Cortex-M1 | |
7 | // - Cortex-M3 | |
8 | // - Cortex-M4(F) | |
9 | // - Cortex-M7(F) | |
a1dfa0c6 | 10 | // - Cortex-M23 |
0731742a | 11 | // - Cortex-M33 |
c30ab7b3 | 12 | // |
0731742a | 13 | // We have opted for these instead of one target per processor (e.g., `cortex-m0`, `cortex-m3`, |
c30ab7b3 SL |
14 | // etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost |
15 | // non-existent from the POV of codegen so it doesn't make sense to have separate targets for them. | |
16 | // And if differences exist between two processors under the same target, rustc flags can be used to | |
17 | // optimize for one processor or the other. | |
18 | // | |
19 | // Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes | |
20 | // difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags | |
21 | // than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to | |
22 | // differentiate one processor from the other. | |
23 | // | |
24 | // About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set, | |
25 | // which is more compact (higher code density), and not the ARM instruction set. That's why LLVM | |
26 | // triples use thumb instead of arm. We follow suit because having thumb in the name let us | |
27 | // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of | |
28 | // build scripts / gcc flags. | |
29 | ||
136023e0 XL |
30 | use crate::spec::TargetOptions; |
31 | use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; | |
c30ab7b3 SL |
32 | |
33 | pub fn opts() -> TargetOptions { | |
34 | // See rust-lang/rfcs#1645 for a discussion about these defaults | |
35 | TargetOptions { | |
29967ef6 | 36 | linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), |
c30ab7b3 | 37 | executables: true, |
b7449926 | 38 | // In most cases, LLD is good enough |
5e7ed085 | 39 | linker: Some("rust-lld".into()), |
c30ab7b3 SL |
40 | // Because these devices have very little resources having an unwinder is too onerous so we |
41 | // default to "abort" because the "unwind" strategy is very rare. | |
42 | panic_strategy: PanicStrategy::Abort, | |
43 | // Similarly, one almost always never wants to use relocatable code because of the extra | |
44 | // costs it involves. | |
f9f354fc | 45 | relocation_model: RelocModel::Static, |
83c7162d XL |
46 | // When this section is added a volatile load to its start address is also generated. This |
47 | // volatile load is a footgun as it can end up loading an invalid memory address, depending | |
48 | // on how the user set up their linker scripts. This section adds pretty printer for stuff | |
49 | // like std::Vec, which is not that used in no-std context, so it's best to left it out | |
50 | // until we figure a way to add the pretty printers without requiring a volatile load cf. | |
51 | // rust-lang/rust#44993. | |
52 | emit_debug_gdb_scripts: false, | |
74b04a01 XL |
53 | // LLVM is eager to trash the link register when calling `noreturn` functions, which |
54 | // breaks debugging. Preserve LR by default to prevent that from happening. | |
136023e0 | 55 | frame_pointer: FramePointer::Always, |
94222f64 XL |
56 | // ARM supports multiple ABIs for enums, the linux one matches the default of 32 here |
57 | // but any arm-none or thumb-none target will be defaulted to 8 on GCC and clang | |
58 | c_enum_min_bits: 8, | |
dfeec247 | 59 | ..Default::default() |
c30ab7b3 SL |
60 | } |
61 | } |