-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[DoNotMerge][WIP] add support for thumb* (Cortex-M) targets #36526
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @arielb1 (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
of the target rather than on its triple (i.e. its name). As explained in rust-lang#35474, the current conditional compilation logic, which is based on the target triple (e.g. x86_64-unknown-linux-gnu), is not robust in the presence of custom targets as those can have arbitrary triples (e.g. cortex-m3). To fix that, this commit changes the conditional compilation logic to use the specification of the target (e.g. target_arch, target_os, etc.). For that, compiler_builtins build script now depends on the rustc-cfg crate, whose role is to shell out to `rustc --print cfg` and return its output parsed as a `struct`. With the goal of completely removing any direct dependency of the conditional compilation logic on the target triple, this commit also exposes the llvm-target field of the target specification via `rustc --print cfg`. closes rust-lang#35474
the Target <-> JSON roundtrip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks @japaric! Could you also add comments to all the new target files indicating what the targets are meant to be used for as well? (e.g. justify target-features and whatnot)
} | ||
|
||
if llvm_target[0] == "thumbv7m" { | ||
cfg.flag("-march=armv7-m"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic should end up in gcc-rs, right?
@@ -13,3 +13,4 @@ core = { path = "../libcore" } | |||
|
|||
[build-dependencies] | |||
gcc = "0.3.27" | |||
rustc-cfg = { git = "https://github.com/japaric/rustc-cfg", branch = "llvm-target" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this may be something that should be in gcc-rs, but maybe I'm missing something? Couldn't we just look at $TARGET
like we do for other platforms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is from #36512. Check that PR for context.
|
||
pub type TargetResult = Result<Target, String>; | ||
|
||
macro_rules! supported_targets { | ||
( $(($triple:expr, $module:ident)),+ ) => ( | ||
( $(($triple:expr, $module:ident)),+, ) => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can actually move the comma inside the parens to require a trailing comma like:
( $(($triple:expr, $module:ident),)+ )
// an impossible value: u64::max_value() because using a valid value like 0 or 8 as the | ||
// default would cause the max-atomic-width field to be "lost" (it would get replaced | ||
// by target_pointer_width) during the Target <-> JSON round trip | ||
max_atomic_width: u64::max_value(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I'm not sure I quite understand why this is necessary, could you elaborate what you mean by "lost" in the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! Let me ellaborate here, first, what happens today without this change:
- All targets go through a round trip from
TargetOptions
to JSON and back toTargetOptions
. - Let's say you set
max_atomic_width
to theDefault
value, which is0
today, for a target specification, when this specification is converted to JSON themax_atomic_width
field is not present in that JSON representation. - When that JSON representation is converted back to
TargetOptions
, the current logic setsmax_atomic_width
totarget_pointer_witdh
, i.e.32
or64
, because themax_atomic_width
field is not present in the JSON representation.
TL;DR You set max_atomic_witdth
to 0
but the compiler is actually using 32
or 64
for the target.
The bug is subtle and the proposed fix is sort of magical. Perhaps we could solve it in a better way.
|
||
options: TargetOptions { | ||
// NOTE prevents mis-optimizations of `ptr::copy_nonoverlapping` when unaligned loads | ||
// are involved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a FIXME or just a NOTE? (e.g. is it a bug we should fix at some point?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After actually checking the documentation. The ARMv6-M Architecture Reference Manual says:
A3.2 Alignment Support
ARMv6-M always generates a fault when an unaligned access occurs.
So no, this can't be "fixed". The architecture doesn't support this operation so it's correct to disable it here.
jemalloc = ["std/jemalloc"] | ||
full = ["core", "std"] | ||
thumb_no_atomics = ["compiler_builtins", "core", "rustc_unicode"] | ||
thumb = ["core", "compiler_builtins", "collections", "rand"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps these could be give non-thumb specific names and just mention no-atomics
and atomics
?
☔ The latest upstream changes (presumably #36719) made this pull request unmergeable. Please resolve the merge conflicts. |
@alexcrichton I don't know if you have have seen it yet. But the tools is considering only adding the target specifications and not building binary artifacts cf. rust-lang/rfcs#1645 (comment). I'll come back to this once that's decided. |
Sounds good to me! |
closing in favor of #36874 which only adds the target definitions |
NOTE Do not merge. rust-lang/rfcs#1645 must be approved first.
As specified in the ("less targets" alternative of the) RFC, this PR adds these new, baseline
targets to the compiler:
thumbv6m-none-eabi
: Cortex-M0, Cortex-M0+, Cortex-M1thumbv7m-none-eabi
: Cortex-M3thumbv7em-none-eabi
: Cortex-M4, Cortex-M7 -- no FPU, soft float ABIthumbv7em-none-eabihf
: Cortex-M4, Cortex-M7 -- SP FPU, hard float ABIAnd tweaks the build script of compiler_builtins to support these targets as well.
With these changes it's possible to compile the following subsets of standard crates for each of
these targets:
thumbv6m-none-eabi
:compiler_builtins
,core
andrustc_unicode
. (*)collections
,compiler_builtins
,rand
and every other crate belowthem.
(*) This target doesn't support atomic operations so crates like
alloc
, which depend on atomics(e.g.
Arc
), and crates above them can't be compiled for this target.TODOs
it that it must compile only the smaller set of crates that each target supports.
cc @alexcrichton @brson