-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Add new Tier 3 targets for ARMv6 #150138
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
base: main
Are you sure you want to change the base?
Add new Tier 3 targets for ARMv6 #150138
Conversation
|
cc @Amanieu, @folkertdev, @sayantn These commits modify compiler targets. Some changes occurred in src/doc/rustc/src/platform-support cc @Noratrieb |
This comment has been minimized.
This comment has been minimized.
696697d to
32cd8e5
Compare
|
Force pushed with fixed formatting |
Targets added in rust-lang/rust#150138. Tested with local build of rustc.
This comment has been minimized.
This comment has been minimized.
|
I think the naming is good. I have reviewed it myself, and would r+, but our policy is that new targets should be approved by a compiler lead, so: r? compiler_leads |
This comment has been minimized.
This comment has been minimized.
This comment was marked as resolved.
This comment was marked as resolved.
| // atomics not available until ARMv6T2 | ||
| atomic_cas: false, | ||
| max_atomic_width: Some(0), |
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.
I suspect this can be implemented using thumb interworking. (If so, I'm not sure if LLVM implements it, but I think I can implement it in portable-atomic.)
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.
What do you suggest I change it to?
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.
I tried max_atomic_width: Some(32) and even with a relaxed load/store I got:
rust-lld: error: undefined symbol: __sync_val_compare_and_swap_4
So for the same reason as ARMv4T and ARMv5TE I propose just switching atomics off here, and letting portable-atomic provide a work-around if it so chooses.
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.
I tried
max_atomic_width: Some(32)and even with a relaxed load/store I got:rust-lld: error: undefined symbol: __sync_val_compare_and_swap_4So for the same reason as ARMv4T and ARMv5TE I propose just switching atomics off here, and letting portable-atomic provide a work-around if it so chooses.
Thanks for confirming. LLVM just generates __sync_* builtins instead of raising errors (like they do for __yield), so I believe the situation is simpler.
I believe more appropriate approach here is to implement the __sync_* builtins in compiler-builtins with instruction_set(arm::a32) and inline assembly.
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.
I believe more appropriate approach here is to implement the
__sync_*builtins in compiler-builtins withinstruction_set(arm::a32)and inline assembly.
Opened rust-lang/compiler-builtins#1050 which implements this approach.
If you and the compiler-builtins maintainer are okay with that approach, we can set the max-atomic-width to 32 and atomic-cas to true for thumbv6-none-eabi after the new compiler-builtins version containing that change is released.
b3c66dd to
02b8038
Compare
This comment has been minimized.
This comment has been minimized.
|
Rebased on main and added some updates based on comments above. |
Targets added in rust-lang/rust#150138. Tested with local build of rustc.
Targets added in rust-lang/rust#150138. Tested with local build of rustc.
|
Changes have been proposed to compiler-builtins which rely on this target, so I'm not sure what order we need to merge these PRs. Maybe merge this where thumbv6 doesn't have CAS, merge the compiler-builtins change, and then update the target to turn CAS on? @taiki-e would this approach also work for ARMv4T and ARMv5TE (which don't have a DMB equivalent CP15 instruction AFAIK)? Because we turned off all atomics for those recently on the grounds it was completely unclear what the sync* functions would need to do. |
It is easier to understand/use if the target consistently provides atomics regardless of the compiler version, so I was thinking merging the compiler-builtins PR first, then including the update to compiler-builtins containing those changes in this PR. (The compiler-builtins PR uses a custom target to ensure it can build even if this PR hasn't been merged yet.)
That approach does not work with v4t and v5te. The reason LLVM cannot generate atomic operations for thumbv6-none-eabi is an LLVM issue where it currently doesn't use thumb interworking for atomic lowing. The reason LLVM cannot generate atomic operations for v4t/v5te is because the ISA doesn't have atomic instructions.
Instructions available only in a32 can be invoked using thumb interworking, but it is not possible to perform operations not present in either instruction set. (The reason v4t/v5te Linux/Android have atomics is that the kernel provides helpers to perform appropriate fallbacks based on the environment, even when atomic instructions are not present in the ISA.) |
This comment was marked as resolved.
This comment was marked as resolved.
02b8038 to
f4826f2
Compare
This comment has been minimized.
This comment has been minimized.
|
Blocked on rust-lang/compiler-builtins#1050, which allows us to support atomics on the thumbv6-none-eabi atomic added here. |
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.
These targets look good to me. Regarding the naming: armv6-* seems fine, we have some arm-* targets that are implicitly v6 but we also already have some armv6-* targets that are explicitly v6. rust-lang/compiler-builtins#1050 seems like the right approach to me, I'll leave it to @taiki-e to advise on what the right order to merge these is for that.
This comment has been minimized.
This comment has been minimized.
|
The EDWG consented to maintainership in rust-embedded/wg#892. |
I don't think this is blocked, right? CI is passing. Atomics just won't work temporarily which is completely fine for a T3 target. Happy to merge with David's review if you can rebase so we don't need to wait for a c-b sync. |
This is a PR for thumbv6-none-eabi (bere-metal Armv6k in Thumb mode) which proposed to be added by rust-lang/rust#150138. Armv6k supports atomic instructions, but they are unavailable in Thumb mode unless Thumb-2 instructions available (v6t2). Using Thumb interworking (can be used via `#[instruction_set]`) allows us to use these instructions even from Thumb mode without Thumb-2 instructions, but LLVM does not implement that processing (as of LLVM 21), so this PR implements it in compiler-builtins. The code around `__sync` builtins is basically copied from `arm_linux.rs` which uses kernel_user_helpers for atomic implementation. The atomic implementation is a port of my [atomic-maybe-uninit inline assembly code]. This PR has been tested on QEMU 10.2.0 using patched compiler-builtins and core that applied the changes in this PR and rust-lang/rust#150138 and the [portable-atomic no-std test suite] (can be run with `./tools/no-std.sh thumbv6-none-eabi` on that repo) which tests wrappers around `core::sync::atomic`. (Note that the target-spec used in test sets max-atomic-width to 32 and atomic_cas to true, unlike the current rust-lang/rust#150138.) The original atomic-maybe-uninit implementation has been tested on real Arm hardware. (Note that Armv6k also supports 64-bit atomic instructions, but they are skipped here. This is because there is no corresponding code in `arm_linux.rs` (since the kernel requirements increased in 1.64, it may be possible to implement 64-bit atomics there as well. see also taiki-e/portable-atomic#82), the code becomes more complex than for 32-bit and smaller atomics.) [atomic-maybe-uninit inline assembly code]: https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/arm.rs [portable-atomic no-std test suite]: https://github.com/taiki-e/portable-atomic/tree/HEAD/tests/no-std-qemu
Three targets, covering A32 and T32 instructions, and soft-float and hard-float ABIs. Hard-float and atomics not available in Thumb mode.
Turns out v7 targets always have v6t2 set, so that line was redundant. Also add a link to the Arm Armv7 A.R.M.
f4826f2 to
aaf0985
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
rust-lang/compiler-builtins#1050 has been merged. I will update this PR to enable 32-bit atomics on these targets, but the The two |
Targets added in rust-lang/rust#150138. Tested with local build of rustc.
This comment has been minimized.
This comment has been minimized.
I don't think that was my fault? |
Will cause LLVM to emit calls to the __sync routines that were added to compiler-builtins in rust-lang/compiler-builtins#1050.
Adds three new targets to support ARMv6 processors running bare-metal:
armv6-none-eabi- Arm ISA, soft-floatarmv6-none-eabihf- Arm ISA, hard-floatthumbv6-none-eabi- Thumb-1 ISA, soft-floatThere is no
thumbv6-none-eabihftarget because as far as I can tell, hard-float isn't support with the Thumb-1 instruction set (and you need the ARMv6T2 extension to enable Thumb-2 support).The targets require ARMv6K as a minimum, which allows the two Arm ISA targets to have full CAS atomics. LLVM has a bug which means it emits some ARMv6K instructions even if you only call for ARMv6, and as no-one else has noticed the bug, and because basically all ARMv6 processors have ARMv6K, I think this is fine. The Thumb target also doesn't have any kind of atomics, just like the Armv5TE and Armv4 targets, because LLVM was emitting library calls to emulate them.
Testing will be added to https://github.com/rust-embedded/aarch32 once the target is accepted. I already have tests for the other non-M arm-none-eabi targets, and those tests pass on these targets.
I have listed myself. If accepted, I'll talk to the Embedded Devices Working Group about adding this one to the rosta with all the others they support.
You might prefer
arm-none-eabi, becausearm-unknown-linux-gnuis an ARMv6 target - the implicit rule seems to be that if the Arm architecture version isn't specified, it's assumed to be v6. However,armv6-none-eabiseemed to fit better betweenarmv5te-none-eabiandarmv7a/armv7r-none-eabi.The hamming distance between
thumbv6-none-eabiandthumbv6m-none-eabiis unfortunately low, but I don't know how to make it better. They are the ARMv6 and ARMv6-M targets, and its perhaps not worse thanarmv7a-none-eabiandarmv7r-none-eabi.No different to any other arm-none-eabi target.
Noted.
Same as other arm-none-eabi targets.
Same as other arm-none-eabi targets.
Noted.
Noted
Noted