(back-port of commit 3f41ecb from 'release-7_6')
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/standard_ao_double_t.h [__aarch64__
&& __ILP32__] (double_ptr_storage): Define as unsigned long long
(instead of unsigned __int128).
/* single-copy atomic (unlike LDREXD for 32-bit ARM). */
do {
__asm__ __volatile__("//AO_double_load\n"
/* 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));
: "=&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"
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));
: "=&r" (result.AO_val1), "=&r" (result.AO_val2), "=&r" (status)
: "Q" (*addr));
} while (AO_EXPECT_FALSE(status));
do {
__asm__ __volatile__("//AO_double_store\n"
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));
: "=&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"
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));
: "=&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"
do {
__asm__ __volatile__("//AO_double_compare_and_swap\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__(
: "=&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));
: "=&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"
do {
__asm__ __volatile__("//AO_double_compare_and_swap_acquire\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__(
: "=&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));
: "=&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"
do {
__asm__ __volatile__("//AO_double_compare_and_swap_release\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__(
: "=&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));
: "=&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"
do {
__asm__ __volatile__("//AO_double_compare_and_swap_full\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__(
: "=&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));
: "=&r" (result), "=Q" (*addr)
: "r" (new_val.AO_val1), "r" (new_val.AO_val2));
} while (AO_EXPECT_FALSE(result));
typedef __m128 double_ptr_storage;
#elif defined(_WIN32) && !defined(__GNUC__)
typedef unsigned __int64 double_ptr_storage;
typedef __m128 double_ptr_storage;
#elif defined(_WIN32) && !defined(__GNUC__)
typedef unsigned __int64 double_ptr_storage;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) && !defined(__ILP32__)
typedef unsigned __int128 double_ptr_storage;
#elif defined(__i386__) && defined(__GNUC__)
typedef unsigned long long double_ptr_storage
typedef unsigned __int128 double_ptr_storage;
#elif defined(__i386__) && defined(__GNUC__)
typedef unsigned long long double_ptr_storage