[PATCH 2/8] atomic: Switch m68k to builtin atomics
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Sep 9 13:03:13 GMT 2025
On 09/09/25 08:14, Wilco Dijkstra wrote:
> Switch m68k to builtin atomics.
>
> Passes buildmanyglibc, OK for commit?
>
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>
> diff --git a/sysdeps/m68k/coldfire/atomic-machine.h b/sysdeps/m68k/coldfire/atomic-machine.h
> index bf90dfd34c64ebb43e4750c17235c26c2a0733b0..644c0e204ebeda7ecfff1f1c712a101caee9ab28 100644
> --- a/sysdeps/m68k/coldfire/atomic-machine.h
> +++ b/sysdeps/m68k/coldfire/atomic-machine.h
> @@ -20,25 +20,9 @@
>
> /* If we have just non-atomic operations, we can as well make them wide. */
> #define __HAVE_64B_ATOMICS 1
> -#define USE_ATOMIC_COMPILER_BUILTINS 0
> +#define USE_ATOMIC_COMPILER_BUILTINS 1
>
> /* XXX Is this actually correct? */
> #define ATOMIC_EXCHANGE_USES_CAS 1
>
> -/* The only basic operation needed is compare and exchange. */
> -#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
> - ({ __typeof (mem) __gmemp = (mem); \
> - __typeof (*mem) __gret = *__gmemp; \
> - __typeof (*mem) __gnewval = (newval); \
> - \
> - if (__gret == (oldval)) \
> - *__gmemp = __gnewval; \
> - __gret; })
> -
> -#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
> - ({ __typeof (mem) __gmemp = (mem); \
> - __typeof (*mem) __gnewval = (newval); \
> - \
> - *__gmemp == (oldval) ? (*__gmemp = __gnewval, 0) : 1; })
> -
> #endif
> diff --git a/sysdeps/m68k/m680x0/m68020/atomic-machine.h b/sysdeps/m68k/m680x0/m68020/atomic-machine.h
> index 9d25fbc194182c9f2dc08fad33031a4de5b2c6bf..f394a20164e69d3c974932327f5a49feeb011d2a 100644
> --- a/sysdeps/m68k/m680x0/m68020/atomic-machine.h
> +++ b/sysdeps/m68k/m680x0/m68020/atomic-machine.h
> @@ -15,218 +15,8 @@
> License along with the GNU C Library. If not, see
> <https://www.gnu.org/licenses/>. */
>
> -#define __HAVE_64B_ATOMICS 1
> -#define USE_ATOMIC_COMPILER_BUILTINS 0
> +#define __HAVE_64B_ATOMICS 0
> +#define USE_ATOMIC_COMPILER_BUILTINS 1
>
> /* XXX Is this actually correct? */
> #define ATOMIC_EXCHANGE_USES_CAS 1
> -
> -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
> - ({ __typeof (*(mem)) __ret; \
> - __asm __volatile ("cas%.b %0,%2,%1" \
> - : "=d" (__ret), "+m" (*(mem)) \
> - : "d" (newval), "0" (oldval)); \
> - __ret; })
> -
> -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
> - ({ __typeof (*(mem)) __ret; \
> - __asm __volatile ("cas%.w %0,%2,%1" \
> - : "=d" (__ret), "+m" (*(mem)) \
> - : "d" (newval), "0" (oldval)); \
> - __ret; })
> -
> -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
> - ({ __typeof (*(mem)) __ret; \
> - __asm __volatile ("cas%.l %0,%2,%1" \
> - : "=d" (__ret), "+m" (*(mem)) \
> - : "d" (newval), "0" (oldval)); \
> - __ret; })
> -
> -# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
> - ({ __typeof (*(mem)) __ret; \
> - __typeof (mem) __memp = (mem); \
> - __asm __volatile ("cas2%.l %0:%R0,%1:%R1,(%2):(%3)" \
> - : "=d" (__ret) \
> - : "d" ((__typeof (*(mem))) (newval)), "r" (__memp), \
> - "r" ((char *) __memp + 4), "0" (oldval) \
> - : "memory"); \
> - __ret; })
> -
> -#define atomic_exchange_acq(mem, newvalue) \
> - ({ __typeof (*(mem)) __result = *(mem); \
> - if (sizeof (*(mem)) == 1) \
> - __asm __volatile ("1: cas%.b %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)) \
> - : "d" (newvalue), "0" (__result)); \
> - else if (sizeof (*(mem)) == 2) \
> - __asm __volatile ("1: cas%.w %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)) \
> - : "d" (newvalue), "0" (__result)); \
> - else if (sizeof (*(mem)) == 4) \
> - __asm __volatile ("1: cas%.l %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)) \
> - : "d" (newvalue), "0" (__result)); \
> - else \
> - { \
> - __typeof (mem) __memp = (mem); \
> - __asm __volatile ("1: cas2%.l %0:%R0,%1:%R1,(%2):(%3);" \
> - " jbne 1b" \
> - : "=d" (__result) \
> - : "d" ((__typeof (*(mem))) (newvalue)), \
> - "r" (__memp), "r" ((char *) __memp + 4), \
> - "0" (__result) \
> - : "memory"); \
> - } \
> - __result; })
> -
> -#define atomic_exchange_and_add(mem, value) \
> - ({ __typeof (*(mem)) __result = *(mem); \
> - __typeof (*(mem)) __temp; \
> - if (sizeof (*(mem)) == 1) \
> - __asm __volatile ("1: move%.b %0,%2;" \
> - " add%.b %3,%2;" \
> - " cas%.b %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)), \
> - "=&d" (__temp) \
> - : "d" (value), "0" (__result)); \
> - else if (sizeof (*(mem)) == 2) \
> - __asm __volatile ("1: move%.w %0,%2;" \
> - " add%.w %3,%2;" \
> - " cas%.w %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)), \
> - "=&d" (__temp) \
> - : "d" (value), "0" (__result)); \
> - else if (sizeof (*(mem)) == 4) \
> - __asm __volatile ("1: move%.l %0,%2;" \
> - " add%.l %3,%2;" \
> - " cas%.l %0,%2,%1;" \
> - " jbne 1b" \
> - : "=d" (__result), "+m" (*(mem)), \
> - "=&d" (__temp) \
> - : "d" (value), "0" (__result)); \
> - else \
> - { \
> - __typeof (mem) __memp = (mem); \
> - __asm __volatile ("1: move%.l %0,%1;" \
> - " move%.l %R0,%R1;" \
> - " add%.l %R2,%R1;" \
> - " addx%.l %2,%1;" \
> - " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
> - " jbne 1b" \
> - : "=d" (__result), "=&d" (__temp) \
> - : "d" ((__typeof (*(mem))) (value)), "r" (__memp), \
> - "r" ((char *) __memp + 4), "0" (__result) \
> - : "memory"); \
> - } \
> - __result; })
> -
> -#define atomic_add(mem, value) \
> - (void) ({ if (sizeof (*(mem)) == 1) \
> - __asm __volatile ("add%.b %1,%0" \
> - : "+m" (*(mem)) \
> - : "id" (value)); \
> - else if (sizeof (*(mem)) == 2) \
> - __asm __volatile ("add%.w %1,%0" \
> - : "+m" (*(mem)) \
> - : "id" (value)); \
> - else if (sizeof (*(mem)) == 4) \
> - __asm __volatile ("add%.l %1,%0" \
> - : "+m" (*(mem)) \
> - : "id" (value)); \
> - else \
> - { \
> - __typeof (mem) __memp = (mem); \
> - __typeof (*(mem)) __oldval = *__memp; \
> - __typeof (*(mem)) __temp; \
> - __asm __volatile ("1: move%.l %0,%1;" \
> - " move%.l %R0,%R1;" \
> - " add%.l %R2,%R1;" \
> - " addx%.l %2,%1;" \
> - " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
> - " jbne 1b" \
> - : "=d" (__oldval), "=&d" (__temp) \
> - : "d" ((__typeof (*(mem))) (value)), \
> - "r" (__memp), "r" ((char *) __memp + 4), \
> - "0" (__oldval) \
> - : "memory"); \
> - } \
> - })
> -
> -#define atomic_increment_and_test(mem) \
> - ({ char __result; \
> - if (sizeof (*(mem)) == 1) \
> - __asm __volatile ("addq%.b %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else if (sizeof (*(mem)) == 2) \
> - __asm __volatile ("addq%.w %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else if (sizeof (*(mem)) == 4) \
> - __asm __volatile ("addq%.l %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else \
> - { \
> - __typeof (mem) __memp = (mem); \
> - __typeof (*(mem)) __oldval = *__memp; \
> - __typeof (*(mem)) __temp; \
> - __asm __volatile ("1: move%.l %1,%2;" \
> - " move%.l %R1,%R2;" \
> - " addq%.l %#1,%R2;" \
> - " addx%.l %5,%2;" \
> - " seq %0;" \
> - " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
> - " jbne 1b" \
> - : "=&dm" (__result), "=d" (__oldval), \
> - "=&d" (__temp) \
> - : "r" (__memp), "r" ((char *) __memp + 4), \
> - "d" (0), "1" (__oldval) \
> - : "memory"); \
> - } \
> - __result; })
> -
> -#define atomic_decrement_and_test(mem) \
> - ({ char __result; \
> - if (sizeof (*(mem)) == 1) \
> - __asm __volatile ("subq%.b %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else if (sizeof (*(mem)) == 2) \
> - __asm __volatile ("subq%.w %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else if (sizeof (*(mem)) == 4) \
> - __asm __volatile ("subq%.l %#1,%1; seq %0" \
> - : "=dm" (__result), "+m" (*(mem))); \
> - else \
> - { \
> - __typeof (mem) __memp = (mem); \
> - __typeof (*(mem)) __oldval = *__memp; \
> - __typeof (*(mem)) __temp; \
> - __asm __volatile ("1: move%.l %1,%2;" \
> - " move%.l %R1,%R2;" \
> - " subq%.l %#1,%R2;" \
> - " subx%.l %5,%2;" \
> - " seq %0;" \
> - " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
> - " jbne 1b" \
> - : "=&dm" (__result), "=d" (__oldval), \
> - "=&d" (__temp) \
> - : "r" (__memp), "r" ((char *) __memp + 4), \
> - "d" (0), "1" (__oldval) \
> - : "memory"); \
> - } \
> - __result; })
> -
> -#define atomic_bit_set(mem, bit) \
> - __asm __volatile ("bfset %0{%1,#1}" \
> - : "+m" (*(mem)) \
> - : "di" (sizeof (*(mem)) * 8 - (bit) - 1))
> -
> -#define atomic_bit_test_set(mem, bit) \
> - ({ char __result; \
> - __asm __volatile ("bfset %1{%2,#1}; sne %0" \
> - : "=dm" (__result), "+m" (*(mem)) \
> - : "di" (sizeof (*(mem)) * 8 - (bit) - 1)); \
> - __result; })
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/atomic-machine.h b/sysdeps/unix/sysv/linux/m68k/coldfire/atomic-machine.h
> index 5f1b232f42ba88789f311dbb91a7e1cdd4c4827b..f8cdc5631ba995b9f58ded6238639149d32fdc30 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/atomic-machine.h
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/atomic-machine.h
> @@ -24,30 +24,11 @@
> kernel provides userspace atomicity operations. Use them. */
>
> #define __HAVE_64B_ATOMICS 0
> -#define USE_ATOMIC_COMPILER_BUILTINS 0
> +#define USE_ATOMIC_COMPILER_BUILTINS 1
>
> /* XXX Is this actually correct? */
> #define ATOMIC_EXCHANGE_USES_CAS 1
>
> -/* The only basic operation needed is compare and exchange. */
> -#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
> - ({ \
> - /* Use temporary variables to workaround call-clobberness of \
> - the registers. */ \
> - __typeof (mem) _mem = mem; \
> - __typeof (oldval) _oldval = oldval; \
> - __typeof (newval) _newval = newval; \
> - register uint32_t _d0 asm ("d0") = SYS_ify (atomic_cmpxchg_32); \
> - register uint32_t *_a0 asm ("a0") = (uint32_t *) _mem; \
> - register uint32_t _d2 asm ("d2") = (uint32_t) _oldval; \
> - register uint32_t _d1 asm ("d1") = (uint32_t) _newval; \
> - \
> - asm ("trap #0" \
> - : "+d" (_d0), "+m" (*_a0) \
> - : "a" (_a0), "d" (_d2), "d" (_d1)); \
> - (__typeof (oldval)) _d0; \
> - })
> -
> # define atomic_full_barrier() \
> (INTERNAL_SYSCALL_CALL (atomic_barrier), (void) 0)
>
>
More information about the Libc-alpha
mailing list