]> granicus.if.org Git - libatomic_ops/commitdiff
Fix ARMv7 LDREXD/STREXD double-wide operand specification (GCC/Clang)
authorIvan Maidanski <ivmai@mail.ru>
Sat, 17 Aug 2013 07:48:59 +0000 (11:48 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 17 Aug 2013 09:30:32 +0000 (13:30 +0400)
* src/atomic_ops/sysdeps/gcc/arm.h (AO_double_load, AO_double_store,
AO_double_compare_and_swap): Specify that LDREXD and STREXD use 2
adjacent registers (thus preventing Clang3.3 from register allocation
failures leading to "registers may not be the same" or
"even register required" GAS errors).

src/atomic_ops/sysdeps/gcc/arm.h

index 18a635531f1dea15541c53276d855f568e4c6c76..a2cca0272fcd73b00965f83a68f816e81abf8ce8 100644 (file)
@@ -499,7 +499,7 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
 
     /* AO_THUMB_GO_ARM is empty. */
     __asm__ __volatile__("@AO_double_load\n"
-      "       ldrexd  %0, [%1]"
+      "       ldrexd  %0, %H0, [%1]"
       : "=&r" (result.AO_whole)
       : "r" (addr)
       /* : no clobber */);
@@ -516,8 +516,8 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
     do {
       /* AO_THUMB_GO_ARM is empty. */
       __asm__ __volatile__("@AO_double_store\n"
-        "       ldrexd  %0, [%3]\n"
-        "       strexd  %1, %4, [%3]"
+        "       ldrexd  %0, %H0, [%3]\n"
+        "       strexd  %1, %4, %H4, [%3]"
         : "=&r" (old_val.AO_whole), "=&r" (status), "+m" (*addr)
         : "r" (addr), "r" (new_val.AO_whole)
         : "cc");
@@ -535,14 +535,14 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
     do {
       /* AO_THUMB_GO_ARM is empty. */
       __asm__ __volatile__("@AO_double_compare_and_swap\n"
-        "       ldrexd  %0, [%1]\n"     /* get original to r1 & r2 */
+        "       ldrexd  %0, %H0, [%1]\n" /* get original to r1 & r2 */
         : "=&r"(tmp)
         : "r"(addr)
         /* : no clobber */);
       if (tmp != old_val.AO_whole)
         break;
       __asm__ __volatile__(
-        "       strexd  %0, %2, [%3]\n" /* store new one if matched */
+        "       strexd  %0, %2, %H2, [%3]\n" /* store new one if matched */
         : "=&r"(result), "+m"(*addr)
         : "r"(new_val.AO_whole), "r"(addr)
         : "cc");