]> granicus.if.org Git - libatomic_ops/commitdiff
Support ILP32 in AArch64 assembly routines (GCC)
authorFrank Schaefer <kelledin@gmail.com>
Wed, 24 Oct 2018 03:11:02 +0000 (22:11 -0500)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 29 Oct 2018 05:12:42 +0000 (08:12 +0300)
Issue #38 (libatomic_ops).

* src/atomic_ops/sysdeps/gcc/aarch64.h [(!__clang__
|| AO_AARCH64_ASM_LOAD_STORE_CAS) && !AO_PREFER_GENERALIZED
&& __ILP32__] (AO_double_load, AO_double_load_acquire, AO_double_store,
AO_double_store_release): Specify the size ("w") of arguments of the
aarch64 instructions.
* src/atomic_ops/sysdeps/gcc/aarch64.h [(!__clang__
|| AO_AARCH64_ASM_LOAD_STORE_CAS) && __ILP32__]
(AO_double_compare_and_swap, AO_double_compare_and_swap_acquire,
AO_double_compare_and_swap_release, AO_double_compare_and_swap_full):
Likewise.

src/atomic_ops/sysdeps/gcc/aarch64.h

index 62b61aa6dae90a9d86d0be154feab30b09c2ccea..680e21fdfa0012ef98637a0616abbdeb099c3eb2 100644 (file)
       /* single-copy atomic (unlike LDREXD for 32-bit ARM).             */
       do {
         __asm__ __volatile__("//AO_double_load\n"
-        "       ldxp  %0, %1, %3\n"
-        "       stxp %w2, %0, %1, %3"
+#       ifdef __ILP32__
+          "       ldxp  %w0, %w1, %3\n"
+          "       stxp %w2, %w0, %w1, %3"
+#       else
+          "       ldxp  %0, %1, %3\n"
+          "       stxp %w2, %0, %1, %3"
+#       endif
         : "=&r" (result.AO_val1), "=&r" (result.AO_val2), "=&r" (status)
         : "Q" (*addr));
       } while (AO_EXPECT_FALSE(status));
 
       do {
         __asm__ __volatile__("//AO_double_load_acquire\n"
-        "       ldaxp  %0, %1, %3\n"
-        "       stxp %w2, %0, %1, %3"
+#       ifdef __ILP32__
+          "       ldaxp  %w0, %w1, %3\n"
+          "       stxp %w2, %w0, %w1, %3"
+#       else
+          "       ldaxp  %0, %1, %3\n"
+          "       stxp %w2, %0, %1, %3"
+#       endif
         : "=&r" (result.AO_val1), "=&r" (result.AO_val2), "=&r" (status)
         : "Q" (*addr));
       } while (AO_EXPECT_FALSE(status));
 
       do {
         __asm__ __volatile__("//AO_double_store\n"
-        "       ldxp  %0, %1, %3\n"
-        "       stxp %w2, %4, %5, %3"
+#       ifdef __ILP32__
+          "       ldxp  %w0, %w1, %3\n"
+          "       stxp %w2, %w4, %w5, %3"
+#       else
+          "       ldxp  %0, %1, %3\n"
+          "       stxp %w2, %4, %5, %3"
+#       endif
         : "=&r" (old_val.AO_val1), "=&r" (old_val.AO_val2), "=&r" (status),
           "=Q" (*addr)
         : "r" (value.AO_val1), "r" (value.AO_val2));
 
       do {
         __asm__ __volatile__("//AO_double_store_release\n"
-        "       ldxp  %0, %1, %3\n"
-        "       stlxp %w2, %4, %5, %3"
+#       ifdef __ILP32__
+          "       ldxp  %w0, %w1, %3\n"
+          "       stlxp %w2, %w4, %w5, %3"
+#       else
+          "       ldxp  %0, %1, %3\n"
+          "       stlxp %w2, %4, %5, %3"
+#       endif
         : "=&r" (old_val.AO_val1), "=&r" (old_val.AO_val2), "=&r" (status),
           "=Q" (*addr)
         : "r" (value.AO_val1), "r" (value.AO_val2));
 
     do {
       __asm__ __volatile__("//AO_double_compare_and_swap\n"
-        "       ldxp  %0, %1, %2\n"
+#       ifdef __ILP32__
+          "       ldxp  %w0, %w1, %2\n"
+#       else
+          "       ldxp  %0, %1, %2\n"
+#       endif
         : "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
         : "Q" (*addr));
       if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
         break;
       __asm__ __volatile__(
-        "       stxp %w0, %2, %3, %1\n"
+#       ifdef __ILP32__
+          "       stxp %w0, %w2, %w3, %1\n"
+#       else
+          "       stxp %w0, %2, %3, %1\n"
+#       endif
         : "=&r" (result), "=Q" (*addr)
         : "r" (new_val.AO_val1), "r" (new_val.AO_val2));
     } while (AO_EXPECT_FALSE(result));
 
     do {
       __asm__ __volatile__("//AO_double_compare_and_swap_acquire\n"
-        "       ldaxp  %0, %1, %2\n"
+#       ifdef __ILP32__
+          "       ldaxp  %w0, %w1, %2\n"
+#       else
+          "       ldaxp  %0, %1, %2\n"
+#       endif
         : "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
         : "Q" (*addr));
       if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
         break;
       __asm__ __volatile__(
-        "       stxp %w0, %2, %3, %1\n"
+#       ifdef __ILP32__
+          "       stxp %w0, %w2, %w3, %1\n"
+#       else
+          "       stxp %w0, %2, %3, %1\n"
+#       endif
         : "=&r" (result), "=Q" (*addr)
         : "r" (new_val.AO_val1), "r" (new_val.AO_val2));
     } while (AO_EXPECT_FALSE(result));
 
     do {
       __asm__ __volatile__("//AO_double_compare_and_swap_release\n"
-        "       ldxp  %0, %1, %2\n"
+#       ifdef __ILP32__
+          "       ldxp  %w0, %w1, %2\n"
+#       else
+          "       ldxp  %0, %1, %2\n"
+#       endif
         : "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
         : "Q" (*addr));
       if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
         break;
       __asm__ __volatile__(
-        "       stlxp %w0, %2, %3, %1\n"
+#       ifdef __ILP32__
+          "       stlxp %w0, %w2, %w3, %1\n"
+#       else
+          "       stlxp %w0, %2, %3, %1\n"
+#       endif
         : "=&r" (result), "=Q" (*addr)
         : "r" (new_val.AO_val1), "r" (new_val.AO_val2));
     } while (AO_EXPECT_FALSE(result));
 
     do {
       __asm__ __volatile__("//AO_double_compare_and_swap_full\n"
-        "       ldaxp  %0, %1, %2\n"
+#       ifdef __ILP32__
+          "       ldaxp  %w0, %w1, %2\n"
+#       else
+          "       ldaxp  %0, %1, %2\n"
+#       endif
         : "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
         : "Q" (*addr));
       if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
         break;
       __asm__ __volatile__(
-        "       stlxp %w0, %2, %3, %1\n"
+#       ifdef __ILP32__
+          "       stlxp %w0, %w2, %w3, %1\n"
+#       else
+          "       stlxp %w0, %2, %3, %1\n"
+#       endif
         : "=&r" (result), "=Q" (*addr)
         : "r" (new_val.AO_val1), "r" (new_val.AO_val2));
     } while (AO_EXPECT_FALSE(result));