]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] GCN: Implement __atomic_compare_exchange_{1,2} in libgcc [PR102215]
authorAndrew Jenner <andrew@codesourcery.com>
Mon, 30 May 2022 10:12:15 +0000 (10:12 +0000)
committerAndrew Jenner <andrew@codesourcery.com>
Mon, 30 May 2022 10:12:15 +0000 (10:12 +0000)
libgcc/ChangeLog:

PR target/102215
* config/gcn/atomic.c (__sync_val_compare_and_swap_##SIZE): Move
a line up to non-arg-dependent value first.
(__ATOMIC_COMPARE_EXCHANGE): Define + call to generate
__atomic_compare_exchange_{1,2}.

libgcc/ChangeLog.omp [new file with mode: 0644]
libgcc/config/gcn/atomic.c

diff --git a/libgcc/ChangeLog.omp b/libgcc/ChangeLog.omp
new file mode 100644 (file)
index 0000000..4d5600e
--- /dev/null
@@ -0,0 +1,7 @@
+2022-03-09  Tobias Burnus  <tobias@codesourcery.com>
+
+       PR target/102215
+       * config/gcn/atomic.c (__sync_val_compare_and_swap_##SIZE): Move
+       a line up to non-arg-dependent value first.
+       (__ATOMIC_COMPARE_EXCHANGE): Define + call to generate
+       __atomic_compare_exchange_{1,2}.
index 1f6ee9e0dfd1f1cf340806e96411ce9f0334ff0f..c0ea6612cdc2c20b5d457b48261d135e71f72a41 100644 (file)
@@ -28,9 +28,9 @@
 TYPE                                                                        \
 __sync_val_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval)     \
 {                                                                           \
+  unsigned int valmask = (1 << (SIZE * 8)) - 1;                                     \
   unsigned int *wordptr = (unsigned int *)((__UINTPTR_TYPE__ ) ptr & ~3UL);  \
   int shift = ((__UINTPTR_TYPE__ ) ptr & 3UL) * 8;                          \
-  unsigned int valmask = (1 << (SIZE * 8)) - 1;                                     \
   unsigned int wordmask = ~(valmask << shift);                              \
   unsigned int oldword = *wordptr;                                          \
   for (;;)                                                                  \
@@ -57,3 +57,30 @@ __sync_bool_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval)    \
 __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned char, 1)
 __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned short, 2)
 
+
+#define __ATOMIC_COMPARE_EXCHANGE(TYPE,SIZE)                                 \
+bool                                                                         \
+__atomic_compare_exchange_##SIZE (TYPE *ptr, TYPE *expected,                 \
+                                 TYPE desired, bool weak,                    \
+                                 int success_memorder, int failure_memorder) \
+{                                                                            \
+  unsigned int valmask = (1 << (SIZE * 8)) - 1;                                      \
+                                                                             \
+  unsigned int *wordptr = (unsigned int *)((__UINTPTR_TYPE__ ) ptr & ~3UL);   \
+  int ptrshift = ((__UINTPTR_TYPE__ ) ptr & 3UL) * 8;                        \
+  unsigned int wordmask = ~(valmask << ptrshift);                            \
+                                                                             \
+  unsigned int ptrword = *wordptr;                                           \
+  unsigned int exptword = ptrword & wordmask;                                \
+  unsigned int newword = ptrword & wordmask;                                 \
+  exptword |= ((unsigned int) *expected) << ptrshift;                        \
+  newword |= ((unsigned int) desired) << ptrshift;                           \
+  if (__atomic_compare_exchange_4 (wordptr, &exptword, newword, weak,        \
+                                  success_memorder, failure_memorder))       \
+    return true;                                                             \
+  *expected = (TYPE) ((exptword >> ptrshift) & valmask);                     \
+  return false;                                                                      \
+}
+
+__ATOMIC_COMPARE_EXCHANGE (unsigned char, 1)
+__ATOMIC_COMPARE_EXCHANGE (unsigned short, 2)