1  /* Copyright (C) 2010-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library.  If not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _ATOMIC_MACHINE_H
      19  #define _ATOMIC_MACHINE_H	1
      20  
      21  #include <sysdep.h>
      22  
      23  /* Coldfire has no atomic compare-and-exchange operation, but the
      24     kernel provides userspace atomicity operations.  Use them.  */
      25  
      26  #define __HAVE_64B_ATOMICS 0
      27  #define USE_ATOMIC_COMPILER_BUILTINS 0
      28  
      29  /* XXX Is this actually correct?  */
      30  #define ATOMIC_EXCHANGE_USES_CAS 1
      31  
      32  /* The only basic operation needed is compare and exchange.  */
      33  #define atomic_compare_and_exchange_val_acq(mem, newval, oldval)	\
      34    ({									\
      35      /* Use temporary variables to workaround call-clobberness of 	\
      36         the registers.  */						\
      37      __typeof (mem) _mem = mem;						\
      38      __typeof (oldval) _oldval = oldval;					\
      39      __typeof (newval) _newval = newval;					\
      40      register uint32_t _d0 asm ("d0") = SYS_ify (atomic_cmpxchg_32);	\
      41      register uint32_t *_a0 asm ("a0") = (uint32_t *) _mem;		\
      42      register uint32_t _d2 asm ("d2") = (uint32_t) _oldval;		\
      43      register uint32_t _d1 asm ("d1") = (uint32_t) _newval;		\
      44  									\
      45      asm ("trap #0"							\
      46  	 : "+d" (_d0), "+m" (*_a0)					\
      47  	 : "a" (_a0), "d" (_d2), "d" (_d1));				\
      48      (__typeof (oldval)) _d0;						\
      49    })
      50  
      51  # define atomic_full_barrier()				\
      52    (INTERNAL_SYSCALL_CALL (atomic_barrier), (void) 0)
      53  
      54  #endif