From 1e26094bdd18c704e1c060e2cf7d2b9bfec037ed Mon Sep 17 00:00:00 2001
From: James Munns <james.munns@gmail.com>
Date: Mon, 2 Oct 2017 15:42:08 +0200
Subject: [PATCH] Allow atomic operations up to 32 bits

The ARMv5te platform does not have instruction-level support for atomics, however the kernel provides [user space helpers](https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt) which can be used to perform atomic operations. When linked with `libc`, the atomic symbols needed by Rust will be provided, rather than CPU level intrinsics.

As this target is specifically `linux` and `gnueabi`, it is reasonable to assume the Linux Kernel and libc will be available for the target. There is a large performance penalty, as we are not using CPU level intrinsics, however this penalty is likely preferable to not having the target at all.

I have used this change in a custom target (along with `xargo`) to build `std`, as well as a number of higher level crates.
---
 src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs
index b95737216787b..97397ca49622e 100644
--- a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs
+++ b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs
@@ -27,8 +27,12 @@ pub fn target() -> TargetResult {
 
         options: TargetOptions {
             features: "+soft-float,+strict-align".to_string(),
-            // No atomic instructions on ARMv5
-            max_atomic_width: Some(0),
+
+            // Atomic operations provided when linked with libgcc.
+            // FIXME: If the following PR is merged, the atomic operations would be
+            // provided by compiler-builtins instead with no change of behavior:
+            // https://github.com/rust-lang-nursery/compiler-builtins/pull/115/files
+            max_atomic_width: Some(32),
             abi_blacklist: super::arm_base::abi_blacklist(),
             .. base
         }