1 /* Low-level functions for atomic operations. Nios II version.
2    Copyright (C) 2012-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #ifndef _NIOS2_ATOMIC_MACHINE_H
20 #define _NIOS2_ATOMIC_MACHINE_H 1
21 
22 #define __HAVE_64B_ATOMICS 0
23 #define USE_ATOMIC_COMPILER_BUILTINS 0
24 
25 /* XXX Is this actually correct?  */
26 #define ATOMIC_EXCHANGE_USES_CAS 1
27 
28 #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval)	\
29   (abort (), (__typeof (*mem)) 0)
30 #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval)	\
31   (abort (), (__typeof (*mem)) 0)
32 #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval)	\
33   (abort (), (__typeof (*mem)) 0)
34 
35 #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval)	\
36   (abort (), 0)
37 #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval)	\
38   (abort (), 0)
39 #define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval)	\
40   (abort (), 0)
41 
42 #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)	\
43   ({									\
44      register int r2 asm ("r2");					\
45      register int* r4 asm ("r4") = (int*)(mem);				\
46      register int r5 asm ("r5");					\
47      register int r6 asm ("r6") = (int)(newval);			\
48      int retval, orig_oldval = (int)(oldval);				\
49      long kernel_cmpxchg = 0x1004;					\
50      while (1)								\
51        {								\
52          r5 = *r4;							\
53 	 if (r5 != orig_oldval)						\
54 	   {								\
55 	     retval = r5;						\
56 	     break;							\
57 	   }								\
58 	 asm volatile ("callr %1\n"					\
59 		       : "=r" (r2)					\
60 		       : "r" (kernel_cmpxchg), "r" (r4), "r" (r5), "r" (r6) \
61 		       : "ra", "memory");				\
62 	 if (!r2) { retval = orig_oldval; break; }			\
63        }								\
64      (__typeof (*(mem))) retval;					\
65   })
66 
67 #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval)	\
68   ({									\
69      register int r2 asm ("r2");					\
70      register int *r4 asm ("r4") = (int*)(mem);				\
71      register int r5 asm ("r5") = (int)(oldval);			\
72      register int r6 asm ("r6") = (int)(newval);			\
73      long kernel_cmpxchg = 0x1004;					\
74      asm volatile ("callr %1\n"						\
75 		   : "=r" (r2)						\
76 		   : "r" (kernel_cmpxchg), "r" (r4), "r" (r5), "r" (r6) \
77 		   : "ra", "memory");					\
78      r2;								\
79   })
80 
81 #define atomic_full_barrier()  ({ asm volatile ("sync"); })
82 
83 #endif /* _NIOS2_ATOMIC_MACHINE_H */
84