-
Notifications
You must be signed in to change notification settings - Fork 99
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
Support older versions of the ARM architecture #25
Comments
What about Cortex-R? You see a few Cortex-R4s around in WiFi processors (I think there's a Cypress/Broadcom one, for example). |
@thejpster I have never dealt with one of those, but I suppose that as long as you create a proper target specification file then things should just work? LLVM seems to support the architecture. |
@japaric @thejpster I know @uvekilledkenny is doing some bare metal work on ARMv4 targets in their Rust on GBA work here: https://github.com/Uvekilledkenny/rba - specifically with the ARM7TDMI the GBA uses. Might be useful to talk to them about it |
@thejpster This looks like a reasonable target specification for the Cortex-R4: {
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"win64",
"sysv64"
],
"arch": "arm",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"env": "",
"executables": true,
"linker": "arm-none-eabi-ld",
"linker-flavor": "ld",
"llvm-target": "armv7r-none-eabi",
"max-atomic-width": 32,
"os": "none",
"panic-strategy": "abort",
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32",
"vendor": ""
} Atomics work in the sense that atomic ops get lowered to |
About max-atomic-width on ARMv5: If I understand it correctly, the PR at rust-lang/compiler-builtins#115 isn't even necessary. LLVM already knows how to call the kernel helpers. I tried it by just setting max-atomic-width to 64. (Not sure if 32 would be more appropriate, but the kernel helpers are available in 64 bit variants, wo why not?) The resulting code compiling some simple rust program looks fine to me. Some random function, only selected because it's short:
where
So it just jumps to Unfortunately, I can't say that rust works on armv5, yet, because I still have some issues which are probably unrelated to atomic operations. I'm still investigating of it's just me doing something stupid or if there's a real issue, I'll report on that later. (My test platform is Lego Mindstorms EV3, which, according to https://en.wikipedia.org/wiki/Lego_Mindstorms_EV3#Overview, contains an ARM926EJ-S CPU.) In conclusion, I think that rust-lang/rust@365ea80 was unnecessary and could be reverted. |
And, as a quick update, using rust beta I actually get a binary which works on the Mindstorm. Just the default 'Hello world' from |
Maybe this changed recently due to the recent LLVM upgrade to 4.0. I certainly recall hitting the "undefined reference" errors when linking a std program for ARMv5. I'm grepping both llvm and compiler-rt sources and I don't the magic cc @Amanieu ^
You could check if the LLVM version is different between master and beta (see |
@japaric These functions are provided by libgcc. |
But LLVM calling In a way atomics being always enabled in libcore but predicated on builtins support is a situation that parallels softfloat being always enabled in libcore but predicated on builtins support. We should treat both the same way IMO. |
@japaric Does it matter if Of course, for some hypothetical |
The implementation of |
When you write 'we could just link with libgcc', does that mean it doesn't happen, now? Then, where does the code quoted above come from? It clearly uses the kernel user helpers, by jumping to |
While I was unable to follow the LLVM source code, using strace on rustc I saw that |
It matters in the sense that we shouldn't break linking of std programs in the future. I recall std programs not linking for ARMv5 before so maybe something changed in the libc crate and we now link to libgcc.a but we didn't before. It would be bad if that changed again and broke linking of the ARMv5 target. I would prefer if the __sync_fetch_and_sub_4 symbols were defined in the compiler-builtins crate that way it would be possible to write std programs that don't depend on C code that use atomics. But I'm obviously biased :-). |
Found the cause for the panic I got with nightly on ARMv5: rust-lang/rust#42314 |
@japaric it is worth noting that as of ~end of 2017, there is now support for the
The atomics mentioned above are even provided by Do we still want to try to get an official |
Good question. Let's discuss that in today meeting. |
Closing this as the armv5 target is now in tree. If there's demand for a built-in armv4 target we can open a new issue. |
FWIW, I have a hobby project (Kobo N416) that is ARMv4 Linux. It's more worthwhile for me to buy a newer Kobo however. |
As of 2017-05-23 Rust officially supports only the ARMv6 and ARMv7 architectures. For ARM Linux, binary releases of std are provided for these targets. For bare metal ARM, there are built-in targets for ARM Cortex-M microcontrollers.
These are two cases that I know of that are currently unsupported:
ARMv5 Linux
std
These targets want to use
std
but from the POV of LLVM these targets don't support atomics as there are no atomic load / store instructions in the instruction set. This leaves these targets with two options:Declare
max-atomic-width
as being 0. This removes atomic types likeAtomicUsize
from libcore making it impossible to build libstd as std depends on those atomic types. The built-in targetarmv5te-unknown-linux-gnueabi
does this.Declare
max-atomic-width
as being 32. With this change libstd can be compiled but trying to link a std program will result in linker errors of the form: "undefined reference to__sync_fetch_and_foo
". As there are no atomic instructions LLVM lower atomic operations to these intrinsics. These intrinsics will have to be provide by the user as there's no implementation for then in the compiler-rt project. One possible implementation for these intrinsics is to use Linux's kernel user helpers as suggested here.uclibc
Some of these targets want to use uclibc instead of glibc because that's what their systems' OS uses. The complication here is that the libc crate does not support uclibc. However the libc crate does compile when compiled for an uclibc target, but it will actually assume that the target is using glibc. This is rather bad because uclibc and glibc don't have the same ABI so using the libc crate for an uclibc target can result in a segfault / crash at runtime.
Important: All std programs make use of the libc crate so all std programs are affected by this issue.
Bare metal ARMv4
I don't have details for this target but since it's a bare metal target it will work in
no_std
mode. A custom target will be required as there's no built-in target in rustc. The specification of that custom target can probably derived from the specification of an existing target.thumbv6m-none-eabi
seems like a good base target:The text was updated successfully, but these errors were encountered: