]> 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>
Sun, 18 Aug 2013 07:49:08 +0000 (11:49 +0400)
(Apply commit db2eef2 from 'master' branch.)

* src/atomic_ops/sysdeps/gcc/arm.h
(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).

Conflicts:

    src/atomic_ops/sysdeps/gcc/arm.h

src/atomic_ops/sysdeps/gcc/arm.h

index e157b613702d48e415e545d88d83fa9785f57f5d..1c5af93f49b4439177ca1ea3d1c95129ec123a3f 100644 (file)
@@ -288,14 +288,14 @@ AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
 
     do {
       __asm__ __volatile__("@AO_compare_double_and_swap_double\n"
-        "       ldrexd  %0, [%1]\n"     /* get original to r1 & r2 */
+        "       ldrexd  %0, %H0, [%1]\n" /* get original to r1 & r2 */
         : "=&r"(tmp)
         : "r"(addr)
         : "cc");
       if (tmp != old_val)
         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), "r"(addr)
         : "cc");